当前位置:   article > 正文

springBoot整合springCache 简化缓存开发_org.springframework.boot.autoconfigure.cache.cache

org.springframework.boot.autoconfigure.cache.cacheproperties

1.)引入依赖 spring-boot-starter-cache和spring-boot-starter-data-redis

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4
<!--引入redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

//TODO 产生堆外内存溢出异常,OutOfDirectMemory
//1).springBoot2.0以后使用lettuce作为操作redis的客户端,它使用netty进行网络通信
//2).lettuce的bug导致netty堆外内存溢出,netty如果没有指定堆外内存,默认使用-Xmx
//3).可以通过-Dio.netty.maxDirectMemory进行设置,不能使用-Dio.netty.maxDirectMemory只去调大堆外内存
//解决方案:

/**
 * 1).升级lettuce客户端,
 * 2).切换使用jedis
 *
 * lettuce,jedis来操作redis的底层客户端,spring在底层对lettuce和jedis进行了再封装redisTemplate
 *
 * @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
 * public class RedisAutoConfiguration
 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.)写配置

(1.)自动配置了哪些? CacheAutoConfiguration会导入 RedisCacheConfiguration;
自动配置好缓存管理器redisCacheManager
在这里插入图片描述

(2.)配置使用redis作为缓存 在properties文件中配置

spring.cache.type=redis
spring.cache.redis.time-to-live=3600000
  • 1
  • 2

3.)测试使用缓存 如下是基本注解的解释
springCache: https://docs.spring.io/spring/docs/5.1.17.RELEASE/spring-framework-reference/integration.html#cache

  •  @Cacheable: Triggers cache population.   触发将数据保存到缓存的操作
    
    • 1
  •  @CacheEvict: Triggers cache eviction.    触发将数据从缓存中删除的操作
    
    • 1
  •  @CachePut: Updates the cache without interfering with the method execution.     不影响方法的执行   更新缓存
    
    • 1
  •  @Caching: Regroups multiple cache operations to be applied on a method.         组合以上操作
    
    • 1
  •  @CacheConfig: Shares some common cache-related settings at class-level.         在类级别共享缓存的相同配置
    
    • 1

1).开启注解功能 @EnableCaching
2).只需要使用注解就可以完成缓存操作
1.1 测试:@Cacheable

/**
     * 1.每一个缓存的数据 我们需要指定放入到哪个名字的缓存
     * 2.@Cacheable({"category"})  //代表当前方法的结果需要进行缓存  如果缓存中有  该方法不调用,如果缓存中没有,会调用方法,最后将方法的结果放入缓存
     * 3.默认行为
     *  1)如果缓存中有,方法不进行调用。
     *  2)key默认自动生成,缓存的名字:SimpleKey[]
     *  3)缓存的value的值,默认使用java序列化机制,将序列化后的数据保存到redis
     *  4)默认ttl时间:-1;  默认ttl时间永不过期
     * /

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
//指定缓存生成的key      key属性:支持springEL表达式  注意字符串要加单引号
//sync = true -->加锁,解决缓存击穿,本地锁足够
@Cacheable(value = {"category"},key = "'level1Categorys'",sync = true)
	public List<CategoryEntity> getLevel1Category()
  • 1
  • 2
  • 3
  • 4

1.2 测试:@Caching 组合以上操作

/**
     * 级联更新所有关联的数据
     * @CacheEvict  缓存失效模式  触发将数据从缓存中删除的操作
     * @param category
     */
//    @CacheEvict(value = {"category"},key = "'getLevel1Categorys'")//单引号
    //同时进行多种缓存操作
    @Caching(evict = {
            @CacheEvict(value = {"category"},key = "'getLevel1Categorys'"),
            @CacheEvict(value = {"category"},key = "'getCatelogJson'")
    })
    public void updateCascade(CategoryEntity category) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.自定义缓存配置

将数据保存为json的格式 自定义RedisCacheConfiguration 即可
参考源码:
在这里插入图片描述

自定义缓存配置:

import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@EnableConfigurationProperties(CacheProperties.class)  //开启配置文件支持
@Configuration
@EnableCaching
public class MyCacheConfig {

//    @Autowired
//    CacheProperties cacheProperties;
    /**
     *
     * @return
     */
    @Bean
    RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){

        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //key和value的序列化器
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));


        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        //让配置文件中的配置生效  ttl等
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

4.springCache的不足

1、读模式

  1. 缓存穿透,查询一个null值 。解决:缓存空数据,properties文件中:spring.cache.redis.cache-null-values=true即可
  2. 缓存击穿,大量并发进来同时查询一个正好过期的数据 。
    解决:加锁大量并发只让一个去查,其他人等待,查到以后释放锁,其他人获取到锁,先查缓存,就会有数据,不用去db查询
  3. 缓存雪崩:缓存雪崩是指在我们设置缓存时key采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩
    解决:原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。如在properties文件配置 spring.cache.redis.time-to-live=3600000

2、写模式

  1. 读写加锁
  2. 引入Cannal,感知到MySQL的更新去更新数据库
  3. 读多写多,直接去数据库查询

总结:
常规数据,(读多写少,及时性,一致性要求不高的数据):完全可以使用spring-Cache解决:写模式
特殊数据:特殊设计

热爱生活 热爱技术 !!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/745051
推荐阅读
相关标签
  

闽ICP备14008679号