前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nc命令卡住不返回的分析

nc命令卡住不返回的分析

作者头像
陈猿解码
发布2023-02-28 14:41:56
2.6K0
发布2023-02-28 14:41:56
举报
文章被收录于专栏:陈猿解码

【概述】


这两天排查解决了一个问题,问题的解决其实很简单,但是整个分析过程还是很有意义的,本文对整个分析过程以及问题如何解决进行总结。

【问题现象】


我们的xxx服务依赖zk,服务在启动之前会检测zk是否处于提供服务的状态,确保启动后可以正确操作zk而不至于异常退出。

具体通过如下命令获取zk的状态:

代码语言:javascript
复制
echo stat | nc 192.168.73.77 2181

出现问题时,发现nc命令一直没有返回,导致无法执行后续的步骤(程序压根没启动)。

【问题排查】


看到问题,第一反应是手动执行一次nc命令,看看是否正常,当然,结果没有令人失望,完全正常。不信邪,再多试几次,nc命令均正确返回退出,并且能获取到对应的状态信息,看来是个偶现问题。

既然命令当前执行都正常,难道是执行nc命令的那个时刻,zk出现了异常导致没有响应?到zk上查看了对应的日志,也没有发现对应时间段有错误的打印。

既然zk都没有错误日志信息,那只能先分析下nc命令当前卡在哪里了。

顺着这个思路,先netstat看了下nc的连接情况,发现与zk的连接处于FIN_WAIT2状态。

熟悉TCP四次挥手的应该都知道,FIN_WAIT2是主动关闭的一方没有收到对端的FIN,从而处于FIN_WAIT2状态(状态变化如下图所示)

对于对端没有对socket关闭的情况,可以快速编写服务端demo进行验证。

例如执行下面脚本:

代码语言:javascript
复制
#!/usr/bin/env python
import socket
import time

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 50000))
s.listen(1)

c,_ = s.accept()
msg=c.recv(1024)
print(msg)
c.sendall('hncscwc')
time.sleep(1000)
c.close()

然后再执行命令,可以发现nc未返回,并且链接处于FIN_WAIT2的状态。

搞清楚了FIN_WAIT2,那么nc卡主和这个又有什么关系呢?带着疑问下载了nmap的源码,查看了下nc执行的相关流程。

内部处理流程本质上就是先建立tcp连接,然后循环处理socket上的可读可写事件,当有可读事件,并且长度为0(EOF)时,回调处理中标记退出循环,然后整个进程也就跟着退出了。

长度为0的可读事件,是收到FIN后,内核协议栈往上发送的可读事件

结合上面说的FIN_WAIT2,就可以知道nc命令为什么不退出了。

通过增加参数“+vvvvvv”查看nc命令执行过程中的输出,对比正常情况和异常情况,可以清楚的看到这一点:

正常退出的情况:

异常不退出的情况:

清楚了问题的所有环节,只剩下为什么nc命令没有收到zk发送的fin了,zk真的可能没有进行socket的关闭吗?还是因为网络问题导致了fin包丢失?

多次复现均未果,而zk的日志也无法提供有力帮助,监控也没有看出当时网络有较大的流量或严重丢包,问题的分析只能作罢。

【问题解决】


虽然不能最终定位是因为zk没有发送close还是因为异常导致了FIN包丢失,但问题终归还是要解决,因此只能从修改使用方式来考虑如何进行规避。

简单man了一把nc,发现有一个"-i"参数,指的是连接的最大读写空闲时间。加上参数,再来进行测试,发现连接虽然处于FIN_WAIT2状态,但等待指定时长后,nc命令返回退出了。

带着参数再看下命令执行过程的输出,发现增加了超时事件,结合源码分析,超时事件的回调处理中也会标记退出循环,从而进程最终也结束退出。

也就是说, "-i"参数是可以正确规避解决问题的。

【总结】


问题比较简单,相关基础知识的融会贯通有助于快速解决问题。另外,多使用man是一个好习惯。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陈猿解码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档