zoukankan      html  css  js  c++  java
  • SpringBoot:第四篇 集成Guava(本地缓存+分布式缓存)

     本地缓存+分布式缓存(redis) 构建二级缓存

    (1)解决redis 热key

    (2)redis缓存io读写,毫秒级响应,本地缓存响应时间更短,亚秒级;对于响应要求更高的服务

    数据读取

    数据修改、删除(先删除本地,然后广播其他节点执行删除)

    1.引入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.3.17.RELEASE</version>
    </dependency>

    2.Guava相关类配置

    (1)GuavaCacheConfig

    package com.example.demo.config;
    
    import com.google.common.cache.CacheBuilder;
    import com.google.common.cache.CacheLoader;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.guava.GuavaCacheManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author duanxiaoqiu
     * @Date 2019-06-15 14:25
     **/
    @EnableConfigurationProperties(GuavaProperties.class)
    @Configuration
    @EnableCaching
    public class GuavaCacheConfig {
    
        @Autowired
        private GuavaProperties guavaProperties;
    
        @Bean
        public CacheBuilder<Object,Object> cacheBuilder(){
            long maximumSize = guavaProperties.getMaximumSize();
            long expireAfterWrite = guavaProperties.getExpireAfterWriteDuration();
            long expireAfterAccess = guavaProperties.getExpireAfterAccessDuration();
            long refreshDuration = guavaProperties.getRefreshDuration();
    
            if(maximumSize <= 0){
                maximumSize = 1024;
            }
            if(expireAfterAccess <= 0){
                expireAfterAccess = 3600;
            }
            if(expireAfterWrite <= 0){
                expireAfterWrite = 3600;
            }
    
            if(refreshDuration <= 0){
                refreshDuration = 1800;
            }
    
            return CacheBuilder.newBuilder().maximumSize(maximumSize)
                    .expireAfterWrite(expireAfterWrite,TimeUnit.SECONDS)
                    .refreshAfterWrite(refreshDuration,TimeUnit.SECONDS);
        }
    
        @Bean(name = "guavaCacheLoader")
        public CacheLoader cacheLoader(){
            return new GuavaCacheLoader();
        }
    
        @Bean
        public CacheManager cacheManager(@Qualifier("cacheBuilder")CacheBuilder cacheBuilder,
                                         @Qualifier("guavaCacheLoader")CacheLoader cacheLoader){
            GuavaCacheManager cacheManager = new GuavaCacheManager();
            cacheManager.setCacheBuilder(cacheBuilder);
            cacheManager.setCacheLoader(cacheLoader);
            return cacheManager;
        }
    
    }
    

    (2)GuavaCacheLoader

    package com.example.demo.config;
    
    import com.google.common.cache.CacheLoader;
    import com.google.common.util.concurrent.ListenableFuture;
    import com.google.common.util.concurrent.ListenableFutureTask;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * @author duanxiaoqiu
     * @Date 2019-06-15 14:34
     **/
    public class GuavaCacheLoader extends CacheLoader<String,String> {
    
        private final ExecutorService executorService = Executors.newFixedThreadPool(4);
    
        @Override
        public String load(String s) throws Exception {
            if (s.equals("hello")) {
                Thread.sleep(3000);
                return "world";
            } else if (s.equals("world")) {
                Thread.sleep(5000);
                return "hello";
            }
            return "no value";
        }
    
        @Override
        public ListenableFuture<String> reload(String key, String oldValue) throws Exception {
            ListenableFutureTask<String> task = ListenableFutureTask.create(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    if (key.equals("hello")) {
                        return "nihao";
                    } else if (key.equals("world")) {
                        return "shijie";
                    }
                    return "no value";
                }
            });
    
            executorService.submit(task);
            return task;
        }
    }
    

    (3)GuavaProperties

    package com.example.demo.config;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    
    /**
     * @author duanxiaoqiu
     * @Date 2019-06-15 14:24
     **/
    @Configuration
    @PropertySource("classpath:guava.properties")
    @ConfigurationProperties(prefix = "guava.cache.config")
    public class GuavaProperties {
    
        private long maximumSize;
    
        private long maximumWeight;
    
        private long expireAfterWriteDuration;
    
        private long expireAfterAccessDuration;
    
        private long refreshDuration;
    
        private int initialCapacity;
    
        private int concurrencyLevel;
    
        public long getMaximumSize() {
            return maximumSize;
        }
    
        public void setMaximumSize(long maximumSize) {
            this.maximumSize = maximumSize;
        }
    
        public long getMaximumWeight() {
            return maximumWeight;
        }
    
        public void setMaximumWeight(long maximumWeight) {
            this.maximumWeight = maximumWeight;
        }
    
        public long getExpireAfterWriteDuration() {
            return expireAfterWriteDuration;
        }
    
        public void setExpireAfterWriteDuration(long expireAfterWriteDuration) {
            this.expireAfterWriteDuration = expireAfterWriteDuration;
        }
    
        public long getExpireAfterAccessDuration() {
            return expireAfterAccessDuration;
        }
    
        public void setExpireAfterAccessDuration(long expireAfterAccessDuration) {
            this.expireAfterAccessDuration = expireAfterAccessDuration;
        }
    
        public long getRefreshDuration() {
            return refreshDuration;
        }
    
        public void setRefreshDuration(long refreshDuration) {
            this.refreshDuration = refreshDuration;
        }
    
        public int getInitialCapacity() {
            return initialCapacity;
        }
    
        public void setInitialCapacity(int initialCapacity) {
            this.initialCapacity = initialCapacity;
        }
    
        public int getConcurrencyLevel() {
            return concurrencyLevel;
        }
    
        public void setConcurrencyLevel(int concurrencyLevel) {
            this.concurrencyLevel = concurrencyLevel;
        }
    }
    

    3.配置文件-- guava.properties

    guava.cache.config.expire-after-write-duration=20
    #更新间隔时长
    guava.cache.config.refresh-duration=10
    guava.cache.config.maximumSize=1024

    4.使用

    package com.example.demo.controller;
    
    /**
     * @author duanxiaoqiu
     * @Date 2019-06-14 15:05
     **/
    
    import com.example.demo.dao.StudentDao;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.CacheManager;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Slf4j
    @Controller
    @RequestMapping("/")
    public class TestController {
    
        @Autowired
        private StudentDao studentDao;
    
        @Autowired
        private CacheManager cacheManager;
    
    
        @RequestMapping("/")
        @ResponseBody
        public String index() {
            log.info(cacheManager.getCache("hello").getName());
    
            log.info("++++");
            return studentDao.getStuById(1).getName() + "hello world";
        }
    
    }

    注:提示idea Spring Boot configuration not found in classpath

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    

    参考文章:

    https://toutiao.io/posts/56yqwd/preview

    https://tech.youzan.com/tmc/

  • 相关阅读:
    有一个实体类,只想返还一部分字段给前端
    Dozer-对象属性映射工具类
    java冒泡排序
    总结Java中的reference类型与四种引用类型
    关于jar包的两种导包方式
    Java Web项目的创建——IDEA+Maven+Tomcat
    关于maven的配置过程
    MYSQL数据库的增删改以及查
    关于linux系统下,出现ERROR 1366 (HY000): Incorrect string value: 'xE6xB4xBBxE5x8AxA8...' for column 'deptN的问题解决方法
    Java Script
  • 原文地址:https://www.cnblogs.com/zgzf/p/11028056.html
Copyright © 2011-2022 走看看