• SSM-spring注解式缓存redis


    目录

    一.redis整合

    1.1.pom配置

     1.2.配置文件spring-redis.xml

    1.3.配置redis的key生成策略

    二.redis的注解式开发及应用场景

    2.1.什么是redis的注解式

     2.2.@Cacheable

    2.3.自定义策略

    2.4.CachePut 注解

     三.redis的击穿穿透雪崩

    1.击穿问题

    2.穿透问题

    3.雪崩问题

     


    一.redis整合

    注1:当spring-context.xml中需要注册多个.properties,那么

    不能在spering-*.xml中添加注册

    注2:resources的配置必须要涵盖读取.preperties 结尾的文件

    注3:redisTemplate的使用,可以参照jdbcTemplate,amqpTemplate,rabbitMQtemplate

    1.1.pom配置

    1. "1.0" encoding="UTF-8"?>
    2. "http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. 4.0.0
    5. org.example
    6. ssm2
    7. 1.0-SNAPSHOT
    8. war
    9. ssm2 Maven Webapp
    10. http://www.example.com
    11. UTF-8
    12. 1.8
    13. 1.8
    14. 3.7.0
    15. 5.0.2.RELEASE
    16. 3.4.5
    17. 5.1.44
    18. 5.1.2
    19. 1.3.1
    20. 2.1.1
    21. 2.4.3
    22. 2.9.1
    23. 4.12
    24. 4.0.0
    25. 1.18.2
    26. 2.10.0
    27. 1.7.7
    28. 2.9.0
    29. 1.7.1.RELEASE
    30. org.springframework
    31. spring-context
    32. ${spring.version}
    33. org.springframework
    34. spring-orm
    35. ${spring.version}
    36. org.springframework
    37. spring-tx
    38. ${spring.version}
    39. org.springframework
    40. spring-aspects
    41. ${spring.version}
    42. org.springframework
    43. spring-web
    44. ${spring.version}
    45. org.springframework
    46. spring-test
    47. ${spring.version}
    48. org.mybatis
    49. mybatis
    50. ${mybatis.version}
    51. mysql
    52. mysql-connector-java
    53. ${mysql.version}
    54. com.github.pagehelper
    55. pagehelper
    56. ${pagehelper.version}
    57. org.mybatis
    58. mybatis-spring
    59. ${mybatis.spring.version}
    60. org.apache.commons
    61. commons-dbcp2
    62. ${commons.dbcp2.version}
    63. org.apache.commons
    64. commons-pool2
    65. ${commons.pool2.version}
    66. org.apache.logging.log4j
    67. log4j-core
    68. ${log4j2.version}
    69. org.apache.logging.log4j
    70. log4j-api
    71. ${log4j2.version}
    72. org.apache.logging.log4j
    73. log4j-web
    74. ${log4j2.version}
    75. junit
    76. junit
    77. ${junit.version}
    78. test
    79. javax.servlet
    80. javax.servlet-api
    81. ${servlet.version}
    82. provided
    83. org.projectlombok
    84. lombok
    85. ${lombok.version}
    86. provided
    87. org.springframework
    88. spring-webmvc
    89. ${spring.version}
    90. javax.servlet.jsp
    91. javax.servlet.jsp-api
    92. 2.3.3
    93. jstl
    94. jstl
    95. 1.2
    96. taglibs
    97. standard
    98. 1.1.2
    99. commons-fileupload
    100. commons-fileupload
    101. 1.3.3
    102. org.hibernate
    103. hibernate-validator
    104. 6.0.7.Final
    105. com.fasterxml.jackson.core
    106. jackson-databind
    107. 2.9.3
    108. com.fasterxml.jackson.core
    109. jackson-core
    110. 2.9.3
    111. com.fasterxml.jackson.core
    112. jackson-annotations
    113. 2.9.3
    114. org.apache.shiro
    115. shiro-core
    116. 1.3.2
    117. org.apache.shiro
    118. shiro-web
    119. 1.3.2
    120. org.apache.shiro
    121. shiro-spring
    122. 1.3.2
    123. net.sf.ehcache
    124. ehcache
    125. ${ehcache.version}
    126. org.slf4j
    127. slf4j-api
    128. ${slf4j-api.version}
    129. org.slf4j
    130. jcl-over-slf4j
    131. ${slf4j-api.version}
    132. runtime
    133. org.apache.logging.log4j
    134. log4j-slf4j-impl
    135. ${log4j2.version}
    136. redis.clients
    137. jedis
    138. ${redis.version}
    139. org.springframework.data
    140. spring-data-redis
    141. ${redis.spring.version}
    142. ssm2
    143. src/main/java
    144. **/*.xml
    145. src/main/resources
    146. *.properties
    147. *.xml
    148. org.apache.maven.plugins
    149. maven-compiler-plugin
    150. ${maven.compiler.plugin.version}
    151. ${maven.compiler.source}
    152. ${maven.compiler.target}
    153. ${project.build.sourceEncoding}
    154. org.mybatis.generator
    155. mybatis-generator-maven-plugin
    156. 1.3.2
    157. mysql
    158. mysql-connector-java
    159. ${mysql.version}
    160. true
    161. maven-clean-plugin
    162. 3.1.0
    163. maven-resources-plugin
    164. 3.0.2
    165. maven-compiler-plugin
    166. 3.8.0
    167. maven-surefire-plugin
    168. 2.22.1
    169. maven-war-plugin
    170. 3.2.2
    171. maven-install-plugin
    172. 2.5.2
    173. maven-deploy-plugin
    174. 2.8.2

     1.2.配置文件spring-redis.xml

    1. "1.0" encoding="UTF-8"?>
    2. "http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:cache="http://www.springframework.org/schema/cache"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans
    7. http://www.springframework.org/schema/beans/spring-beans.xsd
    8. http://www.springframework.org/schema/context
    9. http://www.springframework.org/schema/context/spring-context.xsd
    10. http://www.springframework.org/schema/cache
    11. http://www.springframework.org/schema/cache/spring-cache.xsd">
    12. "poolConfig" class="redis.clients.jedis.JedisPoolConfig">
    13. "maxIdle" value="${redis.maxIdle}"/>
    14. "maxTotal" value="${redis.maxTotal}"/>
    15. "maxWaitMillis" value="${redis.maxWaitMillis}"/>
    16. "minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"/>
    17. "numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"/>
    18. "timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"/>
    19. "testOnBorrow" value="${redis.testOnBorrow}"/>
    20. "testWhileIdle" value="${redis.testWhileIdle}"/>
    21. "connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    22. destroy-method="destroy">
    23. "poolConfig" ref="poolConfig"/>
    24. "hostName" value="${redis.hostName}"/>
    25. "port" value="${redis.port}"/>
    26. "password" value="${redis.password}"/>
    27. "timeout" value="${redis.timeout}"/>
    28. "redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    29. "connectionFactory" ref="connectionFactory"/>
    1. redis.hostName=localhost
    2. redis.port=6379
    3. redis.password=123456
    4. redis.timeout=10000
    5. redis.maxIdle=300
    6. redis.maxTotal=1000
    7. redis.maxWaitMillis=1000
    8. redis.minEvictableIdleTimeMillis=300000
    9. redis.numTestsPerEvictionRun=1024
    10. redis.timeBetweenEvictionRunsMillis=30000
    11. redis.testOnBorrow=true
    12. redis.testWhileIdle=true
    13. redis.expiration=3600

    1.3.配置redis的key生成策略

    1. package com.zking.ssm.redis;
    2. import lombok.extern.slf4j.Slf4j;
    3. import org.springframework.cache.interceptor.KeyGenerator;
    4. import org.springframework.util.ClassUtils;
    5. import java.lang.reflect.Array;
    6. import java.lang.reflect.Method;
    7. @Slf4j
    8. public class CacheKeyGenerator implements KeyGenerator {
    9. // custom cache key
    10. public static final int NO_PARAM_KEY = 0;
    11. public static final int NULL_PARAM_KEY = 53;
    12. @Override
    13. public Object generate(Object target, Method method, Object... params) {
    14. StringBuilder key = new StringBuilder();
    15. key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");
    16. if (params.length == 0) {
    17. key.append(NO_PARAM_KEY);
    18. } else {
    19. int count = 0;
    20. for (Object param : params) {
    21. if (0 != count) {//参数之间用,进行分隔
    22. key.append(',');
    23. }
    24. if (param == null) {
    25. key.append(NULL_PARAM_KEY);
    26. } else if (ClassUtils.isPrimitiveArray(param.getClass())) {
    27. int length = Array.getLength(param);
    28. for (int i = 0; i < length; i++) {
    29. key.append(Array.get(param, i));
    30. key.append(',');
    31. }
    32. } else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) {
    33. key.append(param);
    34. } else {//Java一定要重写hashCode和eqauls
    35. key.append(param.hashCode());
    36. }
    37. count++;
    38. }
    39. }
    40. String finalKey = key.toString();
    41. // IEDA要安装lombok插件
    42. log.debug("using cache key={}", finalKey);
    43. return finalKey;
    44. }
    45. }

    二.redis的注解式开发及应用场景

    2.1.什么是redis的注解式

    @Cacheable 配置在方法或类上,作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果, 下次本方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找

    @CachePut 类似于更新操作,即每次不管缓存中有没有结果,都从数据库查找结果,并将结果更新到缓存,并返回结果

    @CacheEvict 用来清除用在本方法或者类上的缓存数据(用在哪里清除哪里)

     2.2.@Cacheable

    定义查询接口使用Cacheable注解

     

    编写测试类 

     

    测试结果

     再次运行相同的数据时不再查询了,直接从缓冲中拿取数据:

    2.3.自定义策略

    @Cacheable可以指定三个属性,value、key和condition。 

     

    2.4.CachePut 注解

    它的使用与Cacheable的使用一致,它们的区别:

    • Cacheable:会在redis中存储数据,同时也会读取数据
    • CachePut:只会在redis储存数据,不会进行读取操作

     

    测试类

     

    测试结果 

     

     

     三.redis的击穿穿透雪崩

    1.击穿问题

    当一个在缓存中不存在但是经常查询的 key 被请求时,大量的请求会穿透缓存直接到达数据库,导致数据库压力过大,影响系统性能。

    解决方法:
    使用布隆过滤器,将所有可能出现的查询 key 存入布隆过滤器中,如果布隆过滤器返回不存在该 key,则直接返回不存在即可,避免了对底层存储系统的查询操作,减小了数据库的压力。

    2.穿透问题

    当存在大量的恶意请求或者访问不存在的 key 时,这些请求会穿透缓存直接到达底层存储系统,导致底层存储系统压力过大,甚至会导致底层存储系统崩溃。

    解决方法:
    也是使用布隆过滤器,在布隆过滤器返回不存在该 key 时,不再直接查询底层存储系统,而是将请求拦截。

    3.雪崩问题

    当 Redis 缓存中大量的数据过期后,同时有大量请求访问这些已经过期的数据时,这些请求会穿透 Redis 直接到达底层存储系统,导致底层存储系统压力过大,甚至崩溃。

    解决方法:
    使用分布式锁和缓存预热。对于 Redis 中的数据,定期进行缓存预热,提高缓存命中率;同时对于热点数据,可以使用分布式锁,保证在数据过期时,只有一个请求去查询底层存储系统,并在查询完数据后重新设置缓存。

     

  • 相关阅读:
    数据结构与算法-第八章 插入排序
    controller搭建Nova报错
    一个简单的go使用grpc的案例
    网络靶场实战-物联网安全qiling框架初探
    PHP之内置web服务器
    Libgdx游戏开发(1)——环境配置及demo运行
    进程调度的基本过程——请各位不要当渣男~
    k8s TLS bootstrap解析-k8s TLS bootstrap流程分析
    【项目_04】加载时动画效果、跳转详情页、轮播图自定义指示器、搭建详情页 | 基于Vue3全家桶
    Linux主机间的相互免秘钥
  • 原文地址:https://blog.csdn.net/2201_75455485/article/details/134259135