使用若依框架部署了一套系统,之前运行一直没有问题,突然客服那边反馈app经常很卡,进入系统日志查看,发现一堆redis链接超时异常
开始原因分析,显示找到代码,发现问题第一次出现都是在IP限流的一个注解方法里面,该注解使用的是redis script 方式对IP请求次数限流,猜测可能是这个地方导致连接锁定,其他地方在去拿链接就没有了,导致一直超时
改为后发布上线,好了几天,该又出现了,只好问度娘了,百度一搜都是说使用lettuce 这个框架有问题,改用jedis方案才能解决,然后我照着这个方案实现了下,发现跟这个没太大关系,还是一样出现异常,连接一多就挂
lettuce换成jredis
lettuce换成jredis,因为通过用Wireshark发现jredis默认是发心跳包的,而lettuce是不发心跳包的,所以能保持连接状态,更改如下
lettuce换成jredis
lettuce换成jredis,因为通过用Wireshark发现jredis默认是发心跳包的,而lettuce是不发心跳包的,所以能保持连接状态,更改如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
<exclusion>
<artifactId>lettuce-core</artifactId>
<groupId>io.lettuce</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- jedis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool2,使用jedis必须依赖它-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
怎么办呢,只能逐步排查了,既然不是代码的问题,那就猜测是不是服务器的问题了,是不是redis服务器内存还是cpu满了呢,进入一看
都有挺大的余量,应该不是服务器问题,然后在想是不是redis的配置有问题呢,就去找资料,发现redis有个过期策略的机制,默认未配置,在进行到期失效时,回进行数据锁定,这个时候去进行访问,会导致连接挂起,访问一多就会导致连接超时,心里想着很有可能是这个原因,因为在系统中,大量使用了ttl redis的过期回收方法.
redis有六种淘汰策略
noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错。
allkeys-lru:在主键空间中,优先移除最近未使用的key。(推荐)
volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。
allkeys-random:在主键空间中,随机移除某个key。
volatile-random:在设置了过期时间的键空间中,随机移除某个key。
volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除
基于项目的业务,我把redis的过期策略改成了volatile-lru 这样不会影响整体的业务流程,配置方法如下
1.使用vi编辑器进入到redis配置文件redis.conf中
2.查找maxmemory <bytes>
3.设置Redis 内存大小的限制,我们可以设置maxmemory <bytes>,当数据达到限定大小后,会选择配置的策略淘汰数据
比如:maxmemory 4gb。
4.在配置文件中搜索maxmemory-policy,设置Redis的淘汰策略
比如:maxmemory-policy volatile-lru
5、最后重启redis
./redis-server ./redis.conf