目录
SSM项目整合Redis
导入pom依赖
配置文件spring-redis.xml
redis.properties
配置redis的key生成策略
redis的注解式开发及应用场景
什么是redis的注解式
redis注解式的场景应用
@Cacheable
自定义策略
@Cacheable可以指定三个属性,value、key和condition。
编辑 CachePut 注解
redis的击穿 穿透 雪崩
击穿
穿透
雪崩
redis是nosql数据库,mysql是sql数据库,都是数据库因此可以参考mysql整合ssm项目的过程。
以下是在pom.xml文件中添加redis的依赖
4.0.0
org.example
ssm2
1.0-SNAPSHOT
war
ssm2 Maven Webapp
http://www.example.com
UTF-8
1.8
1.8
3.7.0
5.0.2.RELEASE
3.4.5
5.1.44
5.1.2
1.3.1
2.1.1
2.4.3
2.9.1
4.12
4.0.0
1.18.2
2.10.0
1.7.7
2.9.0
1.7.1.RELEASE
org.springframework
spring-context
${spring.version}
org.springframework
spring-orm
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-test
${spring.version}
org.mybatis
mybatis
${mybatis.version}
mysql
mysql-connector-java
${mysql.version}
com.github.pagehelper
pagehelper
${pagehelper.version}
org.mybatis
mybatis-spring
${mybatis.spring.version}
org.apache.commons
commons-dbcp2
${commons.dbcp2.version}
org.apache.commons
commons-pool2
${commons.pool2.version}
org.apache.logging.log4j
log4j-core
${log4j2.version}
org.apache.logging.log4j
log4j-api
${log4j2.version}
org.apache.logging.log4j
log4j-web
${log4j2.version}
junit
junit
${junit.version}
test
javax.servlet
javax.servlet-api
${servlet.version}
provided
org.projectlombok
lombok
${lombok.version}
provided
org.springframework
spring-webmvc
${spring.version}
javax.servlet.jsp
javax.servlet.jsp-api
2.3.3
jstl
jstl
1.2
taglibs
standard
1.1.2
commons-fileupload
commons-fileupload
1.3.3
org.hibernate
hibernate-validator
6.0.7.Final
com.fasterxml.jackson.core
jackson-databind
2.9.3
com.fasterxml.jackson.core
jackson-core
2.9.3
com.fasterxml.jackson.core
jackson-annotations
2.9.3
org.apache.shiro
shiro-core
1.3.2
org.apache.shiro
shiro-web
1.3.2
org.apache.shiro
shiro-spring
1.3.2
net.sf.ehcache
ehcache
${ehcache.version}
org.slf4j
slf4j-api
${slf4j-api.version}
org.slf4j
jcl-over-slf4j
${slf4j-api.version}
runtime
org.apache.logging.log4j
log4j-slf4j-impl
${log4j2.version}
redis.clients
jedis
${redis.version}
org.springframework.data
spring-data-redis
${redis.spring.version}
ssm2
src/main/java
**/*.xml
src/main/resources
*.properties
*.xml
org.apache.maven.plugins
maven-compiler-plugin
${maven.compiler.plugin.version}
${maven.compiler.target}
${project.build.sourceEncoding}
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.2
mysql
mysql-connector-java
${mysql.version}
true
maven-clean-plugin
3.1.0
maven-resources-plugin
3.0.2
maven-compiler-plugin
3.8.0
maven-surefire-plugin
2.22.1
maven-war-plugin
3.2.2
maven-install-plugin
2.5.2
maven-deploy-plugin
2.8.2
创建 redis.properties 进行编写数据连接的信息,包括主机名、端口号、密码
redis.hostName=localhost
redis.port=6379
redis.password=123456
redis.timeout=10000
redis.maxIdle=300
redis.maxTotal=1000
redis.maxWaitMillis=1000
redis.minEvictableIdleTimeMillis=300000
redis.numTestsPerEvictionRun=1024
redis.timeBetweenEvictionRunsMillis=30000
redis.testOnBorrow=true
redis.testWhileIdle=true
redis.expiration=3600
package com.zking.ssm.redis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
@Slf4j
public class CacheKeyGenerator implements KeyGenerator {
// custom cache key
public static final int NO_PARAM_KEY = 0;
public static final int NULL_PARAM_KEY = 53;
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder key = new StringBuilder();
key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");
if (params.length == 0) {
key.append(NO_PARAM_KEY);
} else {
int count = 0;
for (Object param : params) {
if (0 != count) {//参数之间用,进行分隔
key.append(',');
}
if (param == null) {
key.append(NULL_PARAM_KEY);
} else if (ClassUtils.isPrimitiveArray(param.getClass())) {
int length = Array.getLength(param);
for (int i = 0; i < length; i++) {
key.append(Array.get(param, i));
key.append(',');
}
} else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) {
key.append(param);
} else {//Java一定要重写hashCode和eqauls
key.append(param.hashCode());
}
count++;
}
}
String finalKey = key.toString();
// IEDA要安装lombok插件
log.debug("using cache key={}", finalKey);
return finalKey;
}
}
Redis并不支持注解式。注解式是一种常见的编程范式,常见于一些基于Java的框架,如Spring。它允许开发者通过在代码中使用注解来声明一些元数据,以简化配置和提供额外的功能。
然而,在Redis中,我们通常使用客户端库(如Jedis或Lettuce)与Redis进行交互。这些客户端库提供了一组丰富的API来与Redis进行通信,但它们并不支持直接使用注解来实现功能。
当使用Redis时,通常需要手动编写代码来执行各种操作,如存储、检索、更新和删除数据。这些操作通常通过调用客户端库提供的方法来完成,而不是使用注解。
@Cacheable是Spring框架提供的一个缓存注解,用于标记方法的返回结果可以被缓存起来,以提高系统的性能。@Cacheable注解的作用如下
1. 缓存结果:当一个被@Cacheable注解修饰的方法被调用时,Spring会先检查缓存中是否存在该方法的返回结果。如果缓存中已经存在,则直接返回缓存中的结果,而不再执行方法体内的代码逻辑。
2. 缓存键生成:@Cacheable注解可以指定一个缓存键(key)来标识缓存中的数据。默认情况下,缓存键是由方法的参数组成的。如果两次调用的方法参数相同,则会使用相同的缓存键,从而直接返回缓存中的结果。
3. 缓存管理:@Cacheable注解可以与其他缓存管理工具(如Redis、Ehcache等)进行整合使用。通过在配置文件中配置相应的缓存管理器,可以将方法的返回结果存储到指定的缓存中,以供后续的调用使用。
4. 缓存失效:@Cacheable注解还可以指定一个失效时间(TTL)来控制缓存的有效期。当缓存的有效期过期后,下一次调用该方法时会重新执行方法体内的代码逻辑,并将新的结果存储到缓存中。
定义查询接口使用Cacheable注解
编写测试类
它的使用与Cacheable的使用一致,它们的区别
Cacheable:会在redis中存储数据,同时也会读取数据
CachePut:只会在redis储存数据,不会进行读取操作
测试类
缓存中常见的三种现象:击穿、穿透、雪崩。
当缓存中不存在某个key的数据,而有大量并发请求访问这个key时,这些请求会直接穿过缓存,去访问数据库,导致数据库压力过大,甚至宕机。这种现象称为“击穿”。
解决方法:
使用互斥锁或分布式锁,保证只有一个线程去访问数据库,其他线程等待结果即可。
当某个key对应的数据在缓存中不存在,而且这个key被大量请求访问时,这些请求会直接访问数据库,导致数据库压力过大,甚至宕机。这种现象称为“穿透”。
解决方法:
在缓存中预先设置这个key对应的空值或默认值,避免大量请求直接访问数据库。
当缓存中的大量数据同时失效,而且这些数据被大量请求访问时,这些请求会直接访问数据库,导致数据库压力过大,甚至宕机。这种现象称为“雪崩”。
解决方法:
- - 缓存数据的失效时间设置随机,避免大量数据同时失效。
- - 使用多级缓存架构,避免单点故障。
- - 使用熔断机制,当缓存失效时,暂时屏蔽对数据库的访问,避免压力过大。
okok,今天就到这里了,下班!下班!!!!!!!!!!!!