本文首发于 vivo互联网技术 微信公众号
链接: https://mp.weixin.qq.com/s/8f34CaTp--Wz5pTHKA0Xeg
作者:vivo 官网商城开发团队
众所周知,Oracle JDK 是 Java 语言的绝对权威,很多时候 JDK 与 Java 语言近似一个概念。但我们始终要保持实事求是的精神,敢于质疑。本文记录了一次线上troubleshoot 实战,包含问题分析、解决并提交 Oracle JDK bug 的核心过程。
一、背景现象
总之 就是某系统上线后 CLOSE_WAIT数量随着时间增加而大量增加,持续触发多个告警。
二、分析定位过程
部署了一个节点,用来复现之前出现的问题。
Step1 问题聚焦
先查看到底是哪些IP之间的连接产生了大量CLOSE_WAIT,另外系统还会涉及调第三方,总之要确认连接建立的双方。
执行命令:
netstat -np | grep tcp|grep "CLOSE_WAIT"
结果:
(ps:xxx、yyy、zzz 均无含义,基于信息安全考虑,屏蔽掉 ip)。
总之:
yyy.12.230.115
zzz.202.32.241
zzz.202.32.241
这个三个IP是导火索。
Step2 问题分析
这三个IP具体是谁?具体是请求了哪个接口?
暂时无法直接获知!最直接的导火索暂时断了线索。接着从侧面开始查看更多信息,
-
JVM信息
外部资源、线程 什么的都看了,未发现明显异常
-
抓包
要抓包获取更多线索了。对于很久没有碰过TCP层,有些吃力。
得到线索:发现大量的RST
那么是什么操作会导致CLOSE_WAIT呢?什么样的连接导致大量RST呢(可参考RST通常原因)?
Step3 代码分析定位
运维大佬的协助查询,得知这三个IP是图片CDN服务。
至此,可以定位到具体代码逻辑,图片CDN请求可以排查代码。
仔细分析这部分源码后,推测因为服务器 发起 URL请求,请求不存在,导致抛出异常,但是JDK中却没有地方关闭Socket。
javax.imageio.read(URL)
可以看到JDK并没有关闭 ImageIO.read(url) 代码中封装的Socket连接!CDN会请求超时关闭导致服务器处于CLOSE_WAIT?限于网络经验有限,并不能100%确认我的想法。所以模拟下吧。
Step4 复现与模拟
根据系统业务源码,快速模拟:
抓包
TCP查看
问题复现!
Step5 沟通后提报bug
report 给Oracle。
三、Oracle沟通
提单之后,Oracle跟我联系沟通。截取部分邮件内容,仅供参考。
已被采纳
四、疑点与不足
TCP状态机的流转不够熟悉透彻。导致一些问题不能从TCP状态机分析推理,知识的全面精通需要不断提高。
更多内容敬请关注 vivo 互联网技术 微信公众号
注:转载文章请先与微信号:Labs2020 联系。