【概述】


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

【问题现象】


我们的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 times = 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是一个好习惯。

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

nc命令卡住不返回的分析相关推荐

  1. python执行linux命令返回结果_Python中调用Linux命令并获取返回值

    方法一.使用os模块的system方法:os.system(cmd),其返回值是shell指令运行后返回的状态码,int类型,0表示shell指令成功执行,256/512表示未找到,该方法适用于she ...

  2. Python中调用Linux命令并获取返回值

    方法一.使用os模块的system方法: os.system(cmd),其返回值是shell指令运行后返回的状态码,int类型,0表示shell指令成功执行,256/512表示未找到,该方法适用于sh ...

  3. linux—用nc命令监控检测服务器端口

    前端用apache htttpd进行发布(80端口),通过双机负载均衡转发到后端的两个tomcat进行处理(8081和8082端口), 现在需要随时监控这三个端口的情况,一旦down掉需要能够立即告警 ...

  4. linux使用nc命令模拟客户端与服务器,测试连通性

    首先需要安装netcap: mac 可以使用:brew install netcat centos可以参考:解决centos使用nc命令报错:Ncat: Connection refused. 测试连 ...

  5. fastadmin btn-ajax,FastAdmin 在线命令生成时出错的分析

    FastAdmin 在线命令生成时出错的分析 出错现象 版本环境 FastAdmin 版本:1.0.0.20180806_beta 在线命令插件版本:1.0.3 分析 2018-08-13 16:12 ...

  6. Linux Nc命令详解及使用Nc查看Zookeeper的信息

    Linux中nc命令是一个功能强大的网络工具,全称是netcat. 1.语法: nc [-hlnruz][-g<网关...>][-G<指向器数目>][-i<延迟秒数> ...

  7. linux nc命令使用详解

    linux nc命令使用详解 功能说明:功能强大的网络工具 语 法:nc [-hlnruz][-g<网关->][-G<指向器数目>][-i<延迟秒数>][-o< ...

  8. Linux命令之nc命令

    一.命令简介   nc是netcat的简写,是一个功能强大的网络工具,有着网络界的瑞士军刀美誉.nc命令在linux系统中实际命令是ncat,nc是软连接到ncat.nc命令的主要作用如下: 实现任意 ...

  9. nc命令之快速扫描端口--linux命令普及

    今天在做时钟同步调测时,发现本机不能同步到server端的时间. 重启chronyd服务没有用.那我试一试ping 服务器,试了一下是可以ping通的,但是为什么时间同步不上呢? 测试一下端口是否可达 ...

最新文章

  1. 和组内作者consent的模板 亲测有效
  2. java批量执行查询sql语句_详解MyBatis直接执行SQL查询及数据批量插入
  3. JS经典面试题04-原型链Foo.getName
  4. 【LeetCode笔记】238. 除自身以外数组的乘积(Java、思路题)
  5. Win7打印时文档被挂起的解决方法
  6. Qt工作笔记-动态折线图(x轴坐标会改变)
  7. 事业编还是程序员_34岁程序员月薪3万2,跳槽被国企录取,看到月收入后却犹豫了!...
  8. 面向对象的三大特性:封装、继承、多态
  9. 利用后退按钮进行重复提交的解决办法。
  10. adb命令刷机vivox20_vivo手机锁屏密码忘了怎么办?vivo手机强制解锁的三种方法
  11. 如何通过 OAuth 2.0 使 iOS Apps 集成 LinkedIn 登录功能?
  12. 谷歌大牛Jeff Dean单一作者撰文:深度学习研究的黄金十年
  13. 转福布斯荐75本经商必读
  14. DDD中的“领域模型”
  15. Unity2018发布webgl视频无法播放
  16. win7休眠的开启与关闭方法
  17. 如何修改电驴服务器地址,emule设置连接服务器地址
  18. scikit-learn回归类库使用
  19. 宏基台式计算机编号,ACER如何查询型号名称序列号SNID?
  20. 基于深度学习的显著性目标检测方法综述

热门文章

  1. Nvidia Maxine 精讲(一)AR-SDK安装使用——BodyTrack 【非官方全网首发】
  2. MySQL While循环语句
  3. 程序员的工资大概多少?
  4. 项目在使用easyui时遇到的问题
  5. 网站压力测试工具was
  6. Sun Java认证考试介绍
  7. 【人物志】美团前端通道主席洪磊:一位产品出身、爱焊电路板的工程师 1
  8. 专注B2B跨境支付的背后,XTransfer的风控基础设施是如何炼成的?
  9. 谷歌地图各级比例尺及空间分辨率
  10. VirtualBox中Windows 7虚拟机无法全屏显示怎么办?