网络运营

由NFS挂载问题导致snmp服务器处于不可中断睡眠状态的一次故障解决

前言

最近正在为公司搭建一套监控系统,已经完成初步的设备监控模板,并且已经开始监控部分设备了。但第二天发现监控系统出现了一个诡异的情况,监控的数据竟然断断续续,最后变成数据不可达。

系统是通过snmp获取数据的,第一感觉就是snmp服务挂了。因为部署之初是确认好网络可达性的。于是我马上到代理服务器上对服务端发起ping,是正常的。再则发起snmp请求,果然,响应超时。

故障定位

接下来就是各种维度的检查。

首先是检测服务是否挂了,通过ss命令查看端口发现161好好的。说明服务依旧对外监听着请求。接下来尝试重启服务,发现重启过程非常缓慢,花费了将近10秒的操作时间,这显然是异常状态了。

于是,怀疑是系统资源消耗的问题,或者负载队列过大,或者IO阻塞等等。但是发现无论是通过top,还是vmstat,还是ps命令,得到的结果都是:系统负载正常,进程队列在合理范围内,系统资源充足。于是,排除掉系统资源过载的原因。

接下来,检查了配置文件的放行规则,团体名都已经确认无误。而且防火墙策略已经放行代理服务器,端口和资源也没有在系统级别上做限制。另外通过tcpdump命令在161端口抓包,发现客户端的网络通信完全无问题,但是服务器端无任何响应包返回。因此,可以排除系统级别的故障原因了,将原因定位在snmp的服务上。

但是snmp服务理论上并不会无缘无故出故障,昨天的监控还好好的。而且设备都是内网的机器,排除被黑的可能。

在一筹莫展之际,无意中执行了df命令,本想查看下磁盘的使用率。发现df命令卡住了,完全无返回。这种情况和snmp服务器端无返回的情况类似。于是稍微有些头绪。估计在获取某些资源的时候发生阻塞了,而且获取的资源和snmp要获取的资源是相近或者类似。

故障发现

在执行ps命令的时候发现,snmpd服务和df命令时有一个状态是一致的。

之前没了解过这个状态,于是赶紧上网查资料:

Linux进程状态:D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。

与TASK_INTERRUPTIBLE状态类似,进程处于睡眠状态,但是此刻进程是不可中断的。不可中断,指的并不是CPU不响应外部硬件的中断,而是指进程不响应异步信号。
绝大多数情况下,进程处在睡眠状态时,总是应该能够响应异步信号的。否则你将惊奇的发现,kill -9竟然杀不死一个正在睡眠的进程了!于是我们也很好理解,为什么ps命令看到的进程几乎不会出现TASK_UNINTERRUPTIBLE状态,而总是TASK_INTERRUPTIBLE状态。

而TASK_UNINTERRUPTIBLE状态存在的意义就在于,内核的某些处理流程是不能被打断的。如果响应异步信号,程序的执行流程中就会被插入一段用于处理异步信号的流程(这个插入的流程可能只存在于内核态,也可能延伸到用户态),于是原有的流程就被中断了。(参见《linux内核异步中断浅析》)
在进程对某些硬件进行操作时(比如进程调用read系统调用对某个设备文件进行读操作,而read系统调用最终执行到对应设备驱动的代码,并与对应的物理设备进行交互),可能需要使用TASK_UNINTERRUPTIBLE状态对进程进行保护,以避免进程与设备交互的过程被打断,造成设备陷入不可控的状态。这种情况下的TASK_UNINTERRUPTIBLE状态总是非常短暂的,通过ps命令基本上不可能捕捉到。

 

通俗而言,由于程序需要获取某些系统资源会处于阻塞状态。此时如果系统资源无响应,则程序会一直处于阻塞状态不返回任何响应。这种情况大多由于IO阻塞导致的。但是系统上无论是网络IO,还是磁盘IO都是正常的。但网上很多资料介绍关于这种状态通常由于NFS问题导致的,而df命令正好是显示所有挂载的设备文件的使用情况。于是使用命令strace跟踪进程执行时的系统调用和所接收的信号,发现snmpd在响应时和df命令执行时,都卡在同一个地方:

stat(“/var/log”, {st_mode=S_IFDIR|0755, st_size=24576, …}) = 0

stat(“/run/user/0”, {st_mode=S_IFDIR|0700, st_size=40, …}) = 0

stat(“/run/sr-mount/e0f11551-57cc-0ebf-d73b-6cce1426343d”, {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0

stat(“/run/sr-mount/b008823c-18fe-4524-f428-4e8119e0f6e6”, ^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^

故障解决

此时可认为,问题出在stat(“/run/sr-mount/b008823c-18fe-4524-f428-4e8119e0f6e6”,的文件系统挂载上。回忆起昨天有一台NFS的服务器宕机了,对比IP地址果然是宕机的系统的IP。于是,解决的操作就容易了。

  1. 修复宕机的设备
  2. 强制卸载NFS

在选择了第一种解决操作后,问题迎刃而解。数据接收也恢复正常了。

 

总结

在运维的过程中,经常遇到各种千奇百怪的问题。遇到问题时千万不能采取头疼医疼,脚疼医脚的思维方式来处理,需要结合具体的操作环境从多个维度定位问题的原因,同时要善于借助网上的资料。之前我根本没料想到NFS和snmpd这两个服务有何关系,但实践告诉我们,看似毫不相关的两样东西可能具有某种联系,只是还没被发现而已。

Be the First to comment.

Leave a Comment

电子邮件地址不会被公开。 必填项已用*标注