SpringBoot tomcat请求数超过200个 redis连接超限
遇到tomcat莫名其妙无法响应,但是内部日志文件看是有正常打印日志的, 这就是假死情况.
假死的情况无非几种:
redis的连接池资源没释放掉(tcp没释放掉,tcp状态为close_wait)
数据库连接池资源没释放掉(tcp没释放掉,tcp状态为close_wait)
上传文件资源没关闭掉 (tcp没释放掉,tcp状态为close_wait)
httpclient请求没关闭掉 (tcp没释放掉,tcp状态为close_wait)
线程死锁
线程被阻塞了,没继续往下执行
tomcat请求超210个,无法继续服务
检查linux连接情况
ps aux | grep tomcat
ps -T -p pid |wc -lredis连接超限
Redis cluster的最大连接数 = (单个分片的max_clients * 分片数)
查看redis最大连接数, 最大10000,当前有374个,完全没问题.
> info clients
# Clients
connected_clients:374
cluster_connections:0
maxclients:10000
client_recent_max_input_buffer:72
client_recent_max_output_buffer:0
blocked_clients:0
tracking_clients:0
clients_in_timeout_table:0
> config get maxclients
1) "maxclients"
2) "10000"调试查看:
dispatcherServlet进入请求,这一步看来tomcat请求是没问题的.

卡在了拦截器中

内部使用redis存储token.深入进去使用了redis获取token值,

项目中使用的jedis, 进入JedisConnectionFactory 查看获取连接方法.

发现redis连接满了

进入pool.getResource()方法看怎样获取连接的.

如果blockWhenExhausted 为true,则连接最大时,将阻塞获取连接.

当前超过了最大数8个.


检查配置,发现用的不对,因为没使用jedis配置,所以创建了默认最大8,无限阻塞的连接池

为什么没有释放连接,导致超过8个,发现有个定时任务使用了redisTemplate.scan,使用后未关闭,导致连接未释放

修改代码,增加try{}catch()并在return前,关闭cursor, 并修改配置文件
redis:
host: 172.17.97.0
port: 9736
password: FA86D62022
database: 2
jedis:
pool:
enabled: true
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 6000
# 连接池中的最大空闲连接
max-idle: 200
# 连接池中的最小空闲连接
min-idle: 10
# 空闲对象驱逐时间间隔
time-between-eviction-runs: 5000

修改完毕后,观察测试环境运行半个小的JVM快照, 查看jvm堆情况,连接对象没有超2个
