Java堂  


解决Apache出现的CPU高占用率的问题

Filed under: Web&Server — Jet @ 10:06 下午
Tags: ,
原文出处: 解决Apache出现的CPU高占用率的问题
作者: Jet Mah from Java堂
声明: 可以非商业性任意转载, 转载时请务必以超链接形式标明文章原始出处、作者信息及此声明!

所谓Apache出现CPU高占用率就是指Apache在一段时间内持续占用很高的CPU使用率,甚至达到CPU100%,这个时候造成网站无法访问。解决的方法就是仔细观察Apache的日志文件,查阅错误的信息。

下面我们针对几种错误信息进行分析并给出解决的方法:

1. Apache与WinSock v2相冲突
Apache官方提供的手册中提到,在Windows系统下Apache2.x为了提高性能而使用了Microsoft WinSock v2 API,但是一些常见的防火墙软件会破坏他的正确性,从而使得Apache出现死循环操作造成CPU100%。

其错误提示如下所示:

[error] (730038)An operation was attempted on something that is not a socket.: winnt_accept: AcceptEx failed. Attempting to recover.

[error] (OS 10038) : Child 3356: Encountered too many errors accepting client connections. Possible causes: dynamic address renewal, or incompatible VPN or firewall software. Try using the Win32DisableAcceptEx directive.

[warn] (OS 121)信号灯超时时间已到。 : winnt_accept: Asynchronous AcceptEx failed.

[warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed.

可以依次采用下面的方法来解决上面的问题,如果进行了一步还有问题就继续下一步:

1) 在httpd.conf文件中使用 Win32DisableAcceptEx 禁止Apache使用 Microsoft WinSock v2 API :

  1. <IfModule mpm_winnt.c>
  2. Win32DisableAcceptEx # 禁止使用AcceptEx()
  3. </IfModule>

2) 使用System Repair Engineer(SREng)查看WinSocket供应者,如果出现非MS的陌生项则将其删除,并使用软件的“重置WinSocket”按钮进行重置。

3) 卸载与Apache相冲突的杀毒软件或防火墙软件。

如果进行上面的三个步骤之后还有问题,那应该看看是不是还有下面的错误。

2. 是否加载了第三方模块(so文件)
Apache2.x要求所有的第三方模块都必须是线程安全的,但有很多第三方的模块可能存在内存泄露,因此时间一长就可以极大的消耗Apache资源。所以可以采用将所有的第三方模块逐个关闭的方法看看运行一段时间之后Apache对资源的占用是否有所改善。

3. “Terminating 1 threads that failed to exit”错误
上面错误中的数字1有可能是其他数字,造成这个错误的原因是Apache在关闭并发线程的时候出现线程溢出,从而造成内存泄露,表现出来的就是Apache所占用的系统资源持续增长。

具体来说,Apache的子进程在结束当前请求之前会首先将所有的并发线程进行关闭,在关闭的时候会等待3分钟,如果3分钟之内没有将所有的线程关闭则会抛出上述的错误提示,然后强制关闭。这样就造成了内存溢出,时间一长会使得Apache所占用资源持续增长直到无法工作。这个时候可以适当将MaxRequestsPerChild的值降低,使得Apache子进程所并发的线程数量减少,从而降低该错误出现的几率。

但是这种方式并不能彻底解决问题,幸好Apache2.0.x的最新版本(2.0.63)解决了之前版本的这个问题,如果3分钟之内有线程没有关闭的话会自动根据时间情况再增加等待结束的时间直到最终将所有的线程结束。日志文件中会出现类似下面的信息:

Child 1952: Waiting 150 more seconds for 2 worker threads to finish.
Child 1952: Waiting 120 more seconds for 1 worker threads to finish.
Child 1952: All worker threads have exited.

4. “file .\\server\\mpm\\winnt\\child.c, line 1078, assertion “(rv >= 0) && (rv < threads_created)” failed” 错误

这个错误是Apache的一个bug(#11997),可以通过 Win32DisableAcceptEx 禁止Apache使用WinSocket v2来避免此bug,具体设置见前述。

5. PHP5.2.1以上版本的libmysql.dll与MySQL5不兼容
PHP5.2.1以后的新版本(截止目前最新版本为5.2.5)中用于连接MySQL的libmysql.dll组件与MySQL5不兼容,在Apache中运行PHP的时候会造成Apache产生CPU100%的问题。

解决的方法就是从http://www.php.net/releases/下载5.2.1版本,将压缩包中的libmysql.dll文件覆盖现在的文件,然后重启Apache就可以了。

6. 病毒或木马程序命名为Apache.exe
有的时候病毒或木马程序会将其名称命名为Apache.exe文件达到一种掩饰的目的,这个时候使用第三方进程分析器查看进程的路径然后将其删除或使用杀毒软件清除就可以了。

7. 程序编写不严谨造成死循环等错误
如果上面的问题都不存在Apache依然产生CPU100%的问题的话,通常来说就应该是Web程序自身的问题了,例如死循环等等。这个时候需要在日志中设置HTTP请求的文件及执行的时间,然后查找出执行时间比较长的地址进行分析排查。

日志格式设置如下:

LogFormat “%v %h %l %u %t [%Ts] \”%r\” %>s %b” vhost_common #设置程序执行时间

<VirtualHost xxx.xxx.xx.xx:80>
ServerName xxx.xxx.com
DirectoryIndex index.php index.html index.htm
DocumentRoot “xxx”
# cronolog.exe用于将日志文件进行分割的应用程序,可以在 http://cronolog.org/ 下载
CustomLog “|bin/cronolog.exe e:/%Y%m%d.log” vhost_common
</VirtualHost>

参考资料:
apache 遇到[error] (OS 10038) 错误
Error in my_thread_global_end(): 1 threads didn’t exit
Apache 2.2.x (ASF) faulting module errors
Need some advice on Apache 2.2.4 PHP 5.2.3 MYSQL 4.0.26
查看Apache并发请求数及其TCP连接状态
Apache Bug 11997
关于apache.exe开机占用cpu100%的终极解决方法
apache cpu占用100%的问题。
空间持续CPU100%时间过长,如何优化程序

解决dllhost占用CPU 100%的免费方法

Filed under: OS,Web&Server — Jet @ 8:52 上午
原文出处: 解决dllhost占用CPU 100%的免费方法
作者: Jet Mah from Java堂
声明: 可以非商业性任意转载, 转载时请务必以超链接形式标明文章原始出处、作者信息及此声明!

如果在Windows系统中造成CPU100%的话系统会产生延迟,反映到用所访问的站点上面就是等待的时间加长。其实是一个非常复杂的问题,但是如果是因为dllhost占用了CPU100%的话,绝大多数情况下跟IIS有关。产生这种现象的原因主要是:IIS调用ASP组件(即包括自身的也包括第三方的)的时候出现错误,比如IIS无法找到程序中所调用的组件、Access数据库损坏造成ASP操作线程死锁等等;另外一个就是可能中了冲击波病毒,这样只要找一个专杀工具就可以了,本文不在予以描述。

因为所有的IIS组件操作在任务管理器中都是显示的dllhost.exe所占用的状况,如果想查看具体IIS中哪个部分进行操作可以通过“组件服务”来查看。在控制面板中依次打开“管理工具”-“组件服务”,然后依次选择打开“组件服务”-“计算机”-“我的电脑”-“COM+ 应用程序”,然后在上面右键选择菜单中的“查看”-“状态”,这样可以显示正在运行的组件部分。

但是上面的操作只能粗略的查看,很多时候并不能找到出现问题的哪个部分。如果通过百度或者Google搜索的话绝大部分的文章都是提到使用某公司的产品进行监视(明显应该是软文,看来这家公司推广做的不错,呵呵),其实完全没有这个必要,下面同大家分享一下我解决问题的过程。

如果站点中含有Access数据库文件的话首先不管三七二十一先把这些文件用Access压缩修复一下,如果还出现这个问题的话就证明不是Access数据库的问题了。

其实只要能检测IIS执行的时间以及网址(包含参数)并记录下来,然后查看执行时间比较长的链接就是造成CPU100%的罪魁祸首。问题的关键主要是找到出现问题的链接,开始我想自己写一个ISAPI筛选器进行监视,后来无意中发现IIS自带的日志模块本身就有这个功能。右键站点然后选择“属性”打开“网址属性”对话框,在“网站”标签里面最下面选中“启用日志记录”,这里“活动日志格式”一定选择“W3C 扩展日志文件格式”,其他格式没有执行时间选项。这个时候点击右边的“属性”按钮,在“扩展属性”标签“扩展日志记录选项”中选中“URI资源”(执行操作的网址)、“URI查询”、“协议状态”、“所用时间”(后面就基于此选项的内容进行分析)这几个选项。这样记录下来的日志里面就符合我们的要求了,等到发现dellhost又出现CPU100%之后过一段时间(这是因为IIS为了提高操作效率其日志记录中含有一个操作池,只有达到设定的条件之后才会将池中的内容写入到文件中)之后就可以根据执行时间来救出造成dllhost100%的程序文件了。

有的时候系统中不止一个地方出现问题,所以上面的方法可以重复使用。如果这样操作之后还是有问题的话那应该就是IIS自身的问题了,这个时候需要重新安装初始化IIS,具体的方法可以查看火锅城市空间的文章。另外这篇名为《关于站点程序或者ACCESS出错导致DLLHOST.exe占用CPU达100%的监测办法》的文章也值得一读。

参考资料:
dllhost.exe 100% cpu
dllhost.exe CUP使用率100% 解决方法