目录
- 一、场景
- 二、原因
- 三、排查
- 1、使用 `info client` 命令查看redis链接统计情况
- 2、使用 `client list` 命令查看redis链接信息
- 3、关闭程序,看阻塞的链接是否有所减少
- 4、排查使用 `blpop` 命令的相关代码
- 四、解决
一、场景
1、程序在运行一段时间后,会出现没有响应的情况
2、没有报错
3、websocket消息接收正常
4、http请求正常
二、原因
经过排查,发现是redis链接阻塞导致
三、排查
1、使用 info client
命令查看redis链接统计情况
发现阻塞的链接数有132个
2、使用 client list
命令查看redis链接信息
数据太多,这里只贴一部分
将内容复制到文本工具,找一下程序所在的服务器是否有阻塞的redis链接
搜索关键字:flags=b
client list
命令详解:http://t.csdn.cn/2MWxo
3、关闭程序,看阻塞的链接是否有所减少
当时忘记截图了,这里使用文字描述
补充:该程序配置的redis链接数正好是6个,与程序关闭后减少的阻塞的链接数一致
至此,可以确认
1、程序所在服务器确实有链接阻塞
2、使链接阻塞的命令是blpop
4、排查使用 blpop
命令的相关代码
最终发现如下代码
@Override
public void run() {
String key = "redisKey_xxx_xxx_test";
// 死循环
while (true) {
try {
// 封装的工具类,这里指定的阻塞时间为:0L,永久阻塞,问题就在这里
Object o = redisUtil.listPop(key, 0L, TimeUnit.SECONDS);
if (o != null) {
......
}
} catch (Exception e) {
logger.error("线程执行出现异常!详情:" + e.getMessage(), e);
}
}
}
四、解决
调整线程执行逻辑,使redis链接阻塞时间减少
@Override
public void run() {
String key = "redisKey_xxx_xxx_test";
while (true) {
try {
// 获取队列长度,只有队列存在数据才往下走
if (redisUtil.listGetListSize(key) > 0) {
// 封装的工具类,指定阻塞时间为:10秒
Object o = redisUtil.listPop(key, 10L, TimeUnit.SECONDS);
if (o != null) {
......
}
} else {
Thread.sleep(1000);
}
} catch (Exception e) {
logger.error("线程执行出现异常!详情:" + e.getMessage(), e);
}
}
}