Windows Networking 2: 为什么我的Apache服务停不了。

简介: Windows Networking 2: 为什么我的Apache服务停不了。 这是Windows Networking 排查的第二篇,上次涉及了Windows NDIS的架构以及对该架构下网络问题排查的方法。

作者:陈鸽

Windows Networking 2: 为什么我的Apache服务停不了。

这是Windows Networking 排查的第二篇,上次涉及了Windows NDIS的架构以及对该架构下网络问题排查的方法。这次,我们通过一个case,来讲讲NDIS之上,Windows TCPIP 协议栈的实现。

问题

Windows Server 2008 R2 SP1 上,使用Apache部署了服务。当我们尝试停止Apache服务是,该服务一直pending在stopping状态。任何操作都无法恢复,直至重启机器。

方案

在遇到这个问题之前,我们都没有听说过有已知问题会导致Apache服务无法停止,怎么看都是应用的问题。但为避免万一,我们还是经验性的建议,

  1. 卸载不需要的三方软件,尤其是添加了Filter driver或者WFP callout driver的安全软件。
  2. 禁用网卡的高级功能,尤其是TCP Chimney 和 RSS。参考:https://blogs.technet.microsoft.com/onthewire/2014/01/21/tcp-offloadingchimney-rsswhat-is-it-and-should-i-disable-it/
  3. 确认Windows 补丁版本,建议安装最新补丁。
    一一尝试之后,确认问题依旧存在。同时我们确认补丁已经升级到最新。至此,我们常规手段已经无法解决问题,只好通过重现问题并抓取Memory dump做进一步分析。

Memory Dump 分析

从Dump来看,我们明确 Apache的服务进程httpd.exe不退出的原因是Afd.sys驱动在等待一个完成信号。

image.png

由于无法释放afd资源,导致应用程序一直等待,即便强制kill,也会留下zombie进程,只能通过重启解决。

而我们知道,在Windows中AFD资源又是与TCP资源强关联的,只有当对应的TCP资源被释放之后,才会由tcpip.sys调用afd.sys的callback routine,完成释放以及触发信号量的工作。

image.png

因此,更重要的一个问题是TCP资源为什么没有得到释放。因此,我们直接检查TCP资源的Reference,

image.png

在Windows系统中,基本上实现了资源的对象管理。对于TCP的一个端口来说,它也是一个对象。对任何对象的操作之前,系统都会尝试AddReference,避免该对象在使用过程中被释放导致Memory Access Violation。在用完该对象之后,系统会调用DeReference的操作,把减少对应的引用计数。一旦当一个对象的Reference count为0,那么它就会被对应的routine释放。对于一个TCP监听端口来说,释放资源就是tcpip!TcpDereferenceListener,例如,


 # Child-SP  RetAddr   Call Site
00 fffff880`05b727b0 fffff880`0160a01e tcpip!TcpDereferenceListener+0xe
01 fffff880`05b727e0 fffff880`0160a039 tcpip!TcpCloseListener+0x6e
02 fffff880`05b72830 fffff880`02b2fa30 tcpip!TcpTlListenerCloseEndpoint+0x9
03 fffff880`05b72860 fffff880`02b2fef2 afd!AfdCleanupCore+0x410
04 fffff880`05b729e0 fffff800`01937aaf afd!AfdDispatch+0x42
05 fffff880`05b72a30 fffff800`01935a2e nt!IopCloseFile+0x11f
06 fffff880`05b72ac0 fffff800`0193565f nt!ObpDecrementHandleCount+0x8e
07 fffff880`05b72b40 fffff800`01935964 nt!ObpCloseHandleTableEntry+0xaf
08 fffff880`05b72bd0 fffff800`016fd9d3 nt!ObpCloseHandle+0x94
09 fffff880`05b72c20 00000000`7774999a nt!KiSystemServiceCopyEnd+0x13

在我们这个问题中,很明显目前这个80端口对应的TCP资源有超过0x36个引用,除开TcpCreateListener,其它的0x35个引用可能是leak,也可能是其他驱动或者软件在操作这个结构所添加的引用。比如说,netstat 在枚举端口信息的时候会增加端口的reference,例如,

image.png

由于我们明确了系统中没有任何网络相关的三方软件,那么基本上问题就认定为操作系统对于TCP资源的leak。此时,我们基本上就需要跟微软开case,进一步分析操作系统问题。

后记

正当我们准备摩拳擦掌跟微软进一步分析操作系统问题的时候,我们在微软网站上偶尔的发现7月10日发布的最新补丁可能会引发w3svc无法停止的问题,尽管不是Apache,但是问题的描述跟我们发现的本质问题一致,

https://support.microsoft.com/en-us/help/4338818/windows-7-update-kb4338818

image.png

微软在之后紧急release了新的update 4345459来修复该问题。

https://support.microsoft.com/en-us/help/4345459/stop-error-0xd1-after-a-race-condition-occurs-in-windows-7-service-pac

在我们的这个case中,应用该补丁之后,问题解决。

相关文章
|
6天前
|
安全 关系型数据库 虚拟化
WIndows Server 远程桌面服务—RDS
WIndows Server 远程桌面服务—RDS
|
6天前
|
开发框架 JavaScript 安全
WIndows Server 2016 部署 Web服务(简单篇)
WIndows Server 2016 部署 Web服务(简单篇)
|
6天前
|
Windows
Windows2016 搭建 DHCP服务
Windows2016 搭建 DHCP服务
|
10天前
|
监控 安全 虚拟化
深入浅出:NSSM封装Windows服务工具的使用与介绍
深入浅出:NSSM封装Windows服务工具的使用与介绍
21 3
|
10天前
|
网络安全 API Apache
如何在win系统部署Apache服务并实现无公网ip远程访问
如何在win系统部署Apache服务并实现无公网ip远程访问
|
11天前
|
关系型数据库 MySQL PHP
如何在Windows安装Wnmp服务并实现固定地址远程访问
如何在Windows安装Wnmp服务并实现固定地址远程访问
|
22天前
|
网络协议 安全 文件存储
Windows如何使用IIS服务搭建本地WebDAV网站并实现远程管理储存文件
Windows如何使用IIS服务搭建本地WebDAV网站并实现远程管理储存文件
|
22天前
|
网络协议 安全 测试技术
Windows安装禅道系统结合Cpolar实现公网访问内网BUG管理服务
Windows安装禅道系统结合Cpolar实现公网访问内网BUG管理服务
|
22天前
|
机器学习/深度学习 安全 数据安全/隐私保护
Windows系统安装Jupyter Notebook并实现公网访问内网笔记服务
Windows系统安装Jupyter Notebook并实现公网访问内网笔记服务
|
25天前
|
存储 Linux 数据库
ZooKeeper【搭建 01】apache-zookeeper-3.6.2 单机版安装+配置+添加到service服务+开机启动配置+验证+chkconfig配置(一篇入门zookeeper)
【4月更文挑战第8天】ZooKeeper【搭建 01】apache-zookeeper-3.6.2 单机版安装+配置+添加到service服务+开机启动配置+验证+chkconfig配置(一篇入门zookeeper)
38 0

推荐镜像

更多