9 月 082008
 

作者: 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.
   2. Win32DisableAcceptEx # 禁止使用AcceptEx()
   3.

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

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

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

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

解决的方法也很简单,将最大请求线程的值降低一些,但是也不能太低,太低的话会产生大量的请求队列从而造成站点访问缓慢。如果之前为0则将其设置为一个最大值。

   1. MaxRequestsPerChild 10000

3. “file .\\server\\mpm\\winnt\\child.c, line 1078, assertion “(rv >= 0) && (rv < threads_created)” failed” 错误 这个错误是Apache的一个bug(#11997),可以通过 Win32DisableAcceptEx 禁止Apache使用WinSocket v2来避免此bug,具体设置见前述。 4. 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就可以了。

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

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

日志格式设置如下:

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

    
    ServerName xxx.xxx.com
    DirectoryIndex index.php index.html index.htm
    DocumentRoot “xxx”
    # cronolog.exe是Apache自带的用于将日志文件进行分割的应用程序
    CustomLog “|bin/cronolog.exe e:/%Y%m%d.log” vhost_common
    

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

  1条评论 到 “解决Apache出现的CPU高占用率的问题”

  1. Apache日志问题解决集

       前言:今天图片服务器出现了问题,访问速度很慢。检查Apache的日志发现中间有一个错误N多。
    [warn] (OS 64)指定的网络名不再可用。  : winnt_accept: Asynchronous AcceptEx failed.
    而且写入速度急快每秒钟要写入6条错误记录。最后查找了相关的资料解决了问题。并把一些其它的日志问题都合到一起,虽然还没有碰到过,也许以后会碰到,以后碰到新的也要把这些问题合到一起方便自己。
    问题一、
    Apache日志中“指定的网络名不再可用”问题的解决
    现象:
    [Sat Mar 03 13:29:49 2007] [warn] (OS 64)指定的网络名不再可用。  : winnt_accept: Asynchronous AcceptEx failed.
    出现这个故障时硬盘灯狂闪,内存占用极大,访问极慢。
    分析:
    AcceptEx() 是 Microsoft WinSock v2 API 一组提升网路效率 API 中的指令。而且在 Windows 上似乎蛮有可能出问题的。
          注:可能為了效能还是预设為开啟 AcceptEx()
    解决:
         如果无预警的发生问题,我猜可能是 Windows Update 或是防火墙、防毒软体更新了某些网路原件,造成 Microsoft WinSock v2 API 动作不正常,这时可以把这个功能先给关掉。
          依照官方说明 , Win32DisableAcceptEx 这个功能,只有 2.0.49 版以后的才可以使用,所以我猜测 AcceptEx() 这个指令大概也是 2.0.49 才会开始支援(目前最新的就是 2.0.49)。

          关掉 AcceptEx() 的方式只要在 httpd.conf 找到 <IfModule mpm_winnt.c> 区段,加入 Win32DisableAcceptEx 就可以了。

    <IfModule mpm_winnt.c>
    Win32DisableAcceptEx #加入这一行
    ThreadsPerChild 250
    MaxRequestsPerChild 0
    </IfModule>

    疑问:如果把AcceptEx()这个关掉了,是否会影响访问的速度;如果影响速度,又怎样不让速度慢下来。
    问题二、
    apache错误日志里面出现"connection reset by peer"
    分析:
        这个问题一般是客户端在连接还没有完全建立的时候就取消连接,比如用户按了浏览器上面的“停止”按钮,一般来说没有什么问题。但是如果频繁出现,就表示很多客户端连接到Apache服务器的响应时间太长了,可能是网络的问题或者服务器性能问题。
    问题三、
    apache错误日志里面提示default.ida或者cmd.exe不存在
    分析:
        这个说明Internet上面的某些机器中了蠕虫病毒比如Nimda或者Code Red。 你可以略过这些错误,因为这些病毒对Apache无效。
    问题四、
    apache错误日志里面出现"fcntl: F_SETLKW: No record locks available
    现象:
       服务器挂起,或者不能启动,错误日志里面出现"fcntl: F_SETLKW: No record locks available"或者类似的信息。
    分析:
      这个是文件锁定问题,表示Apache服务器在尝试使用一个NFS文件系统上面的同步文件。由于使用并行操作模式,Apache服务器在访问某些特定资源的时候需要一些同步机制。其中一种同步机制就是文件锁定,这个需要被锁定文件那端的文件系统要支持锁定机制,所以使用NFS文件系统上面的文件会出现这种问题。
    解决:
       为了解决NFS文件系统的局限性,可以在配置文件里面加入一行:
        LockFile /var/run/apache-lock
        这个文件对其他人必须是不能写入的。
        注意:Redhat Linux7.x版本以后已经提供了NFS锁定机制,应该不会出现此问题。

回复ocean 取消回复

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>