博客
关于我
Redis使用不当导致应用卡死
阅读量:795 次
发布时间:2023-02-28

本文共 1049 字,大约阅读时间需要 3 分钟。

内网沙盒环境中,我们遇到了API持续卡死的问题,所有API无响应。刚开始测试人员反映响应慢,重启应用后恢复正常,但后来问题频发,越来越多同事抱怨,怀疑代码存在问题。经过排查,发现本地IDE环境没有异常,数据库、Redis均正常,无特殊错误日志,初步怀疑是沙盒环境机器问题。

SSH上服务器执行top命令,发现机器状态正常,但仍有疑虑。打算查看JVM堆栈信息,先查看问题应用较耗资源的线程,执行top -H -p 12798,找到前3个相对比较耗资源的线程。接着使用jstack查看堆内存,分析线程状态,发现大量线程处于锁定状态,但未发现业务相关代码,暂时无头绪。

为了保护现场,dump了问题进程的堆内存,进入调试模式重启测试环境应用,等待问题再次出现后远程调试问题机器。第二天问题再现,通知运维将Nginx转发取消问题应用,自己远程调试Tomcat。

随意找一个接口,断点在入口处,发现API等待服务响应,未进入断点。尝试在AOP之前打断点,发现进入断点,F8步进后发现执行Redis命令时卡主。继续跟踪,发现问题出在Jedis的连接获取过程。

进一步分析发现,pool.getResource()后线程开始wait状态。查看pool配置,发现未配置MaxWaitMillis,尝试配置后问题依旧。继续追踪,发现线程处于锁状态,使用Arthas诊断工具,发现大量http-nio线程处于waiting状态。

详细分析发现,问题是由于Redis连接获取问题,原因是pool配置不合理,未设置MaxWaitMillis。配置后重启服务,等待一天,问题再次复现。检查Tomcat accesslog,发现大量API请求出现500错误。

追踪500错误,发现问题出在stringRedisTemplate的使用方式上。stringRedisTemplate.getConnectionFactory().getConnection()获取连接后未正确释放,导致Redis连接池中连接未归还。正确使用RedisCallback执行时,操作完成后使用RedisConnectionUtils.releaseConnection()释放连接。

总结:使用stringRedisTemplate执行特定命令时,应采用RedisCallback方式,并正确释放连接。避免直接使用getConnection(),以免影响连接池状态。合理配置Redis pool,避免长时间等待,确保连接及时释放,避免阻塞和资源浪费。

转载地址:http://aktfk.baihongyu.com/

你可能感兴趣的文章
PHP 插入排序 -- 折半查找
查看>>
PHP 支持8种基本的数据类型
查看>>
php 放大镜,放大镜放大图片效果
查看>>
php 数据库 表格数据,php数据库到excel表格-php怎么把数据库数据放到表格里
查看>>
PHP 数据库连接池实现
查看>>
php 数组 区别,PHP中数组的区别
查看>>
PHP 数组怎么添加一个元素
查看>>
PHP 文件上传
查看>>
PHP 文件操作
查看>>
php 文字弹幕效果代码,HTML5文字弹幕效果
查看>>
php 时间日期函数,获取今天开始时间,结束时间
查看>>
PHP 构造函数的重载
查看>>
php 标准规范
查看>>
PHP 浮点型精度运算相关问题
查看>>
php 浮点型计算精度问题
查看>>
php 特定时间段统计,jpgraph某个时间段的数据统计
查看>>
php 生成csv mac下乱码
查看>>
php 生成证书 签名及验签
查看>>
php 的rsa加密与解密
查看>>
PHP 的标准输入与输出
查看>>