SpringBoot:第五篇 集成Guava(本地缓存+分布式缓存)

简介: SpringBoot:第五篇 集成Guava(本地缓存+分布式缓存)

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/


相关文章
|
25天前
|
缓存 NoSQL Java
什么是缓存?如何在 Spring Boot 中使用缓存框架
什么是缓存?如何在 Spring Boot 中使用缓存框架
39 0
|
22天前
|
XML Java API
Spring Boot集成MinIO
本文介绍了如何在Spring Boot项目中集成MinIO,一个高性能的分布式对象存储服务。主要步骤包括:引入MinIO依赖、配置MinIO属性、创建MinIO配置类和服务类、使用服务类实现文件上传和下载功能,以及运行应用进行测试。通过这些步骤,可以轻松地在项目中使用MinIO的对象存储功能。
|
22天前
|
缓存 NoSQL Java
Spring Boot中的分布式缓存方案
Spring Boot提供了简便的方式来集成和使用分布式缓存。通过Redis和Memcached等缓存方案,可以显著提升应用的性能和扩展性。合理配置和优化缓存策略,可以有效避免常见的缓存问题,保证系统的稳定性和高效运行。
38 3
|
24天前
|
消息中间件 Java Kafka
什么是Apache Kafka?如何将其与Spring Boot集成?
什么是Apache Kafka?如何将其与Spring Boot集成?
59 5
|
28天前
|
存储 Java 关系型数据库
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
49 6
|
27天前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
40 1
|
1月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
41 5
|
1月前
|
XML Java 数据库连接
SpringBoot集成Flowable:打造强大的工作流管理系统
在企业级应用开发中,工作流管理是一个核心组件,它能够帮助我们定义、执行和管理业务流程。Flowable是一个开源的工作流和业务流程管理(BPM)平台,它提供了强大的工作流引擎和建模工具。结合SpringBoot,我们可以快速构建一个高效、灵活的工作流管理系统。本文将探讨如何将Flowable集成到SpringBoot应用中,并展示其强大的功能。
215 1
|
27天前
|
消息中间件 监控 Java
您是否已集成 Spring Boot 与 ActiveMQ?
您是否已集成 Spring Boot 与 ActiveMQ?
52 0
|
4天前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
118 85