记生产环境Java线程假死处理记录

运行及编译环境:
Centos 7 | jdk8 | Tomcat 8
该服务主要功能:读取本地数据,回传至云端接口中。

简略运行流程如下:

Created with Raphaël 2.3.0 开始 查询本地数据库 判断是否上传云端 从本地ftp服务器获取 调用云端上传接口 结束 yes no

现场:

A.当数据量比较少时,运行正常,无假死情况出现。
B.当数据量较多时,偶发出现假死情况。

分析:

  1. 初步怀疑是 Linux 内核参数限制 TCP 连接数,导致无法获取新的 TCP 连接导致。
    根据阿里云Linux实例常用内核网络参数介绍与常见问题处理中,关于存在大量处于TIME_WAIT状态的连接的处理,当前服务器内核参数设置正常,排除该问题。
  2. 查询本地数据库代码中,设置了超时时间,排除该步骤问题。
  3. 判断是否上云操作
    该操作会调用云端接口,使用commons-httpclent包为依赖调用接口;经查询代码得知,未设置 ReadTimeout 属性,仅设置 ConnectTimeout 属性,怀疑为读取超时导致该问题;
    设置 ReadTimeout 属性后,运行一段时间时候,依然出现假死情况。
  4. 最开始,并未怀疑使用FTP读取本地文件时会连接超时,使用 jmap 生成dump文件进行分析,发现线程处于RUNNABLE状态,查看 trace 记录得知,在 FTP 获取文件流时超时,至此故障找到,设置 超时时间即可解决问题。
// 生成dump 文件命令
// 首先获取 java 在Linux文件中进程PID,然后执行:
jmap -dump:file=javaDump.hprof,format=b 7129
// 7129 为线程PID,根据实际修改即可
// 使用jdk自带 jvisualvm.exe 工具进行分析

总结:
实际生产环境中,代码调用链比较长,并没有本文流程图所示流程那么简单,所以问题排查比较麻烦。
本文是基于实际环境做了简化提炼,仅为记录处理过程。
主要是在写http请求代码中,并未设置超时时间导致,引以为戒!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值