一整套线上故障排查技巧,爱了( 六 )


在线上时 , 我们可以直接用命令 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'来查看 time-wait 和 close_wait 的数量 。
用 ss 命令会更快 ss -ant | awk '{++S[$1]} END {for(a in S) print a, S[a]}':
一整套线上故障排查技巧,爱了文章插图
TIME_WAIT:time_wait 的存在一是为了丢失的数据包被后面连接复用 , 二是为了在 2MSL 的时间范围内正常关闭连接 。
它的存在其实会大大减少 RST 包的出现 。 过多的 time_wait 在短连接频繁的场景比较容易出现 。
这种情况可以在服务端做一些内核参数调优:
#表示开启重用 。 允许将TIME-WAIT sockets重新用于新的TCP连接 , 默认为0 , 表示关闭net.ipv4.tcp_tw_reuse = 1#表示开启TCP连接中TIME-WAIT sockets的快速回收 , 默认为0 , 表示关闭net.ipv4.tcp_tw_recycle = 1当然我们不要忘记在 NAT 环境下因为时间戳错乱导致数据包被拒绝的坑了 , 另外的办法就是改小 tcp_max_tw_buckets , 超过这个数的 time_wait 都会被干掉 , 不过这也会导致报 time wait bucket table overflow 的错 。
CLOSE_WAIT:close_wait 往往都是因为应用程序写的有问题 , 没有在 ACK 后再次发起 FIN 报文 。
close_wait 出现的概率甚至比 time_wait 要更高 , 后果也更严重 。 往往是由于某个地方阻塞住了 , 没有正常关闭连接 , 从而渐渐地消耗完所有的线程 。
想要定位这类问题 , 最好是通过 jstack 来分析线程堆栈来排查问题 , 具体可参考上述章节 。 这里仅举一个例子 。
开发同学说应用上线后 CLOSE_WAIT 就一直增多 , 直到挂掉为止 , jstack 后找到比较可疑的堆栈是大部分线程都卡在了 countdownlatch.await 方法 。
找开发同学了解后得知使用了多线程但是确没有 catch 异常 , 修改后发现异常仅仅是最简单的升级 SDK 后常出现的 class not found 。
一整套线上故障排查技巧,爱了文章插图
之前 , 给大家发过三份Java面试宝典 , 这次新增了一份 , 目前总共是四份面试宝典 , 相信在跳槽前一个月按照面试宝典准备准备 , 基本没大问题 。

  • 《java面试宝典5.0》(初中级)
  • 《350道Java面试题:整理自100+公司》(中高级)
  • 《资深java面试宝典-视频版》(资深)
  • 《Java[BAT]面试必备》(资深)
分别适用于初中级 , 中高级 , 资深级工程师的面试复习 。
内容包含java基础、javaweb、mysql性能优化、JVM、锁、百万并发、消息队列 , 高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper、数据结构、限流熔断降级等等 。
一整套线上故障排查技巧,爱了文章插图
看到这里 , 证明有所收获