nc命令卡住不返回的分析

【概述】


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

【问题现象】


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

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

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进行验证。

例如执行下面脚本:

#!/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是一个好习惯。

原创不易,点赞,在看,分享是最好的支持, 谢谢~

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\]和引用\[2\]的内容,nc命令Linux下的一个用于调试和检查网络的工具包,可用于创建TCP/IP连接和处理TCP/UDP套接字。在引用\[1\]中提到,可以通过在终端输入"nc -lk 端口号"来监听指定端口。而在引用\[2\]中提到,可以通过"nc -v ip_address port"来与指定IP地址和端口建立连接。所以,如果nc命令不可用,可能是因为没有正确安装或配置nc工具包。您可以尝试通过安装nc工具包来解决这个问题。 #### 引用[.reference_title] - *1* [解决win10 下NC(瑞士军刀)的无法使用的问题](https://blog.csdn.net/weixin_39094101/article/details/104319429)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [CentOS解决 -bash: nc: command not found 问题](https://blog.csdn.net/qq_25231683/article/details/125276635)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [linux系统nc命令使用](https://blog.csdn.net/subfate/article/details/122959499)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值