spring-boot整合redis操作
1. 引入redis的starterpom.xml
org.springframework.boot
spring-boot-starter-data-redis
2.1.8.RELEASE
2. 配置redis
application.yml
spring:
redis:
host: 192.168.31.125
password:
port: 6379
3. 引入stringRedisTemplate
@Autowired
StringRedisTemplate stringRedisTemplate;
...
@Test
public void testRedis(){
//保存
ValueOperations ops = stringRedisTemplate.opsForValue();
ops.set("hello","world_" + UUID.randomUUID().toString());
//查询
String hello = ops.get("hello");
System.out.println(hello);
}
运行测试:
2021-11-22 15:40:40.198 INFO 13260 --- [ main] c.a.n.client.config.impl.ClientWorker : [fixed-127.0.0.1_8848-561fc56a-09b9-4827-afff-dc46de5469ed] [subscribe] mybatis.yml+dev+561fc56a-09b9-4827-afff-dc46de5469ed 2021-11-22 15:40:40.198 INFO 13260 --- [ main] c.a.nacos.client.config.impl.CacheData : [fixed-127.0.0.1_8848-561fc56a-09b9-4827-afff-dc46de5469ed] [add-listener] ok, tenant=561fc56a-09b9-4827-afff-dc46de5469ed, dataId=mybatis.yml, group=dev, cnt=1 2021-11-22 15:40:41.043 INFO 13260 --- [ main] io.lettuce.core.EpollProvider : Starting without optional epoll library 2021-11-22 15:40:41.046 INFO 13260 --- [ main] io.lettuce.core.KqueueProvider : Starting without optional kqueue library world_b96c7f9c-3dbc-45ae-85f1-0bd47a9f512c
客户端登录检查:
模拟一段真实逻辑:
public Map> getCatalogJson() { //给缓存存放json 拿出的json字符串需要逆转为对象类型【序列化与反序列化】 //1.从缓存取出的json String redisString = stringRedisTemplate.opsForValue().get(RedisConstant.INDEX_CATALOGJSON); if(StringUtils.isEmpty(redisString)){ System.out.println("经过查数据库..."); //2.缓存中没有 查询数据库 Map > catlogJsonFromDb = getCatalogJsonFromDb(); //3. 数据库查询结构 转成json保存缓存 redisString = JSON.toJSONString(catlogJsonFromDb); stringRedisTemplate.opsForValue().set(RedisConstant.INDEX_CATALOGJSON,redisString); } //2. - 直接把缓存取出结果 逆转指定类型 Map > result = JSON.parseObject(redisString, new TypeReference< Map >>(){}); return result; } public Map > getCatalogJsonFromDb() { //数据库逻辑 return res; }
结果展示:
首次调用数据库 存储redis消耗了6283ms
后续的直接redis获取数据消耗之多在百毫秒级别。
对性能有明显的提升
拓展
记录一个谷粒学院大神解决问题的过程:
springboot整合redis后,做压力测试或者长时间线上运行后产生:堆外内存溢出 OutOfDirectMemoryError
分析:
springboot2.0以后默认使用的lettuce作为操作redis的客户端。它使用netty进行网络通信。
leetuce的bug导致netty对外内存溢出。 大神翻阅代码后找出 netty的底层自己会统计内存容量使用量,netty会根据开销减去内存剩余量。推测netty客户端某处操作时,没有及时释放内存触发异常。
大神提出两个方案解决:
1升级lettuce客户端 2.更换使用jedis
大神操作是更换jedis(截至目前lettuce没有好的解决方案)
原先的pom.xml
org.springframework.boot spring-boot-starter-data-redis 2.1.8.RELEASE
修改(剔除lettuce 增加jedis):
org.springframework.boot spring-boot-starter-data-redis io.lettuce lettuce-core redis.clients jedis 2.1.8.RELEASE
大神的补充讲解:
redisTemplate:
lettuce 、jedis两者都是操作redis底层客户端,封装了redis的一些api.redisTemplate是对这两者的在此封装。
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
...
...
redisTemplate有基于这两者的连接工厂类,所以这两者可以替换。



