ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

手把手教你使用 Spring Boot 3 开发上线一个前后端分离的生产级系统(六) - 本地缓存 Caffeine 和 分布式缓存 Redis 集成与配置

2022-05-29 06:31:14  阅读:154  来源: 互联网

标签:缓存 管理器 CacheConsts Boot Caffeine caffeine CacheEnum


本地缓存 Caffeine 集成和配置

Caffeine 是 Java 8 对 Google Guava 缓存的重写,是一个提供了近乎最佳命中率的高性能的缓存库。我们按照如下步骤集成和配置:

  1. 添加 spring-boot-starter-cache 依赖

使用 spring-boot-starter-cache “Starter” 可以快速添加基本缓存依赖项。 starter 引入了 spring-context-support。如果我们手动添加依赖项,则必须包含 spring-context-support 才能使用 JCache 或 Caffeine 支持。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
  1. 添加 caffeine 依赖
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>
  1. 自定义缓存管理器
/**
    * Caffeine 缓存管理器
    */
@Bean
public CacheManager caffeineCacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();

    List<CaffeineCache> caches = new ArrayList<>(CacheConsts.CacheEnum.values().length);
    for (CacheConsts.CacheEnum c : CacheConsts.CacheEnum.values()) {
        if (c.isLocal()) {
            Caffeine<Object, Object> caffeine = Caffeine.newBuilder().recordStats().maximumSize(c.getMaxSize());
            if (c.getTtl() > 0) {
                caffeine.expireAfterWrite(Duration.ofSeconds(c.getTtl()));
            }
            caches.add(new CaffeineCache(c.getName(), caffeine.build()));
        }
    }

    cacheManager.setCaches(caches);
    return cacheManager;
}
  1. 使用 @EnableCaching 注解开启缓存
@SpringBootApplication
@MapperScan("io.github.xxyopen.novel.dao.mapper")
@EnableCaching
@Slf4j
public class NovelApplication {

	public static void main(String[] args) {
		SpringApplication.run(NovelApplication.class, args);
	}

	@Bean
	public CommandLineRunner commandLineRunner(ApplicationContext context){
		return args -> {
			Map<String, CacheManager> beans = context.getBeansOfType(CacheManager.class);
			log.info("加载了如下缓存管理器:");
			beans.forEach((k,v)->{
				log.info("{}:{}",k,v.getClass().getName());
				log.info("缓存:{}",v.getCacheNames());
			});

		};
	}

}

这样我们就可以使用 Spring Cache 的注解(例如 @Cacheable)开发了。

分布式缓存 Redis 集成和配置

本地缓存虽然有着访问速度快的优点,但无法进行大数据的存储。并且当我们集群部署多个服务节点,或者后期随着业务发展进行服务拆分后,没法共享缓存和保证缓存数据的一致性。
本地缓存的数据还会随应用程序的重启而丢失,这样对于需要持久化的数据满足不了需求,还会导致重启后数据库瞬时压力过大。

所以本地缓存一般适合于缓存只读数据,如统计类数据,或者每个部署节点独立的数据。其它情况就需要用到分布式缓存了。

分布式缓存的集成步骤和本地缓存基本差不多,除了替换 caffeine 的依赖项为我们 redis 的依赖和配置上我们自定义的 redis 缓存管理器外,还要在配置文件中加入 redis 的连接配置:

  1. 加入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 配置 redis 缓存管理器
/**
 * 缓存配置类
 *
 * @author xiongxiaoyang
 * @date 2022/5/12
 */
@Configuration
public class CacheConfig {

    /**
     * Caffeine 缓存管理器
     */
    @Bean
    @Primary
    public CacheManager caffeineCacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();

        List<CaffeineCache> caches = new ArrayList<>(CacheConsts.CacheEnum.values().length);
        for (CacheConsts.CacheEnum c : CacheConsts.CacheEnum.values()) {
            if (c.isLocal()) {
                Caffeine<Object, Object> caffeine = Caffeine.newBuilder().recordStats().maximumSize(c.getMaxSize());
                if (c.getTtl() > 0) {
                    caffeine.expireAfterWrite(Duration.ofSeconds(c.getTtl()));
                }
                caches.add(new CaffeineCache(c.getName(), caffeine.build()));
            }
        }

        cacheManager.setCaches(caches);
        return cacheManager;
    }

    /**
     * Redis 缓存管理器
     */
    @Bean
    public CacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);

        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .disableCachingNullValues().prefixCacheNameWith(CacheConsts.REDIS_CACHE_PREFIX);

        Map<String, RedisCacheConfiguration> cacheMap = new LinkedHashMap<>(CacheConsts.CacheEnum.values().length);
        for (CacheConsts.CacheEnum c : CacheConsts.CacheEnum.values()) {
            if (c.isRemote()) {
                if (c.getTtl() > 0) {
                    cacheMap.put(c.getName(), RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues()
                            .prefixCacheNameWith(CacheConsts.REDIS_CACHE_PREFIX).entryTtl(Duration.ofSeconds(c.getTtl())));
                } else {
                    cacheMap.put(c.getName(), RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues()
                            .prefixCacheNameWith(CacheConsts.REDIS_CACHE_PREFIX));
                }
            }
        }

        RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig, cacheMap);
        redisCacheManager.setTransactionAware(true);
        redisCacheManager.initializeCaches();
        return redisCacheManager;
    }

}
  1. application.yml 中加入 redis 连接配置信息
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456

标签:缓存,管理器,CacheConsts,Boot,Caffeine,caffeine,CacheEnum
来源: https://www.cnblogs.com/xxyopen/p/16322775.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有