- A+
在公司做OA系统的调优,某国产OA垃圾得要命,发个通知居然会卡,查了一下,居然是Apache有个配置问题,导致影响了效率,解决合集如下。
都是转的:
其一:
近来点击玩聚热点故事,偶尔遇到500错误,看了看Apache2.2.3日志(Windows2003下的),注意到如下错误丫的总出现:
[warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed.
以前也看到,但忽略了。这回不能再放过她了。
看了几篇(winnt(MPM) - Apache 2.2 中文版参考手册),说是因为一些流行的Windows产品,比如防病毒软件或虚拟专用网络软件,会干扰AcceptEx()的正确操作。于是在apache配置文件中添加如下语句:
<IfModule mpm_winnt.c> ThreadsPerChild 1000 MaxRequestsPerChild 10000 Win32DisableAcceptEx </IfModule>
停止Apache,再启动。确实新配置起作用了:
[notice] Disabled use of AcceptEx() WinSock2 API
[notice] mod_python: Creating 8 session mutexes based on 0 max processes and 1000 max threads.
[notice] Child 2380: Child process is running
[notice] Child 2380: Acquired the start mutex.
[notice] Child 2380: Starting 1000 worker threads.
okay,似乎错误不再来了
其二:
在Apache的logs/error.log中经常出现如下记录:
[Fri Mar 16 17:28:49 2007] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed. [Fri Mar 16 17:28:49 2007] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed. [Fri Mar 16 17:28:50 2007] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed. [Fri Mar 16 17:28:50 2007] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed. [Fri Mar 16 17:28:50 2007] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed. [Fri Mar 16 17:28:50 2007] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed. [Fri Mar 16 17:28:50 2007] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed.
出现这个故障时硬盘灯狂闪,内存占用极大,导致网站访问极慢。
解决方法:
Apache 关闭 AcceptEx() ,这个在Windows平台下适用
方法是在 httpd.conf 内加入 Win32DisableAcceptEx 。
Win32DisableAcceptEx 顾名思义就是在 Windows 下关掉 AcceptEx() 功能的指令。至於 AcceptEx() 这个东西是什么,可以参考 Apache 的官方网页:
http://httpd.apache.org/docs-2.0 … in32disableacceptex
QUOTE:
AcceptEx() is a Microsoft WinSock v2 API that provides some performance improvements over the use of the BSD style accept() API in certain circumstances. Some popular Windows products, typically virus scanning or virtual private network packages, have bugs that interfere with the proper operation of AcceptEx(). If you encounter an error condition like:
[error] (730038)An operation was attempted on something that is not a socket.: winnt_accept: AcceptEx failed. Attempting to recover.
you should use this directive to disable the use of AcceptEx().
主要是说这 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 就可以了。
QUOTE:
<IfModule mpm_winnt.c> Win32DisableAcceptEx EnableMMAP Off EnableSendfile Off ThreadsPerChild 1700 MaxRequestsPerChild 0 </IfModule>
然后重新启动动 Apache,“指定的网络名不再可用”再也不出现了
其三:
没遇到过..帮你找了个资料不知有没有用:
为了这个问题简直是伤透了心,拖拖拉拉了很长时间也没有解决,这阵子咬咬牙,查遍了相关资料,终于把一堆办法划拉到一起,似乎解决了这个问题。方法很简单,但是似乎不同的服务器有不同的解决方法。
大体解决思路有这么几种:
1 apache与服务器的杀毒软件和防火墙冲突,导致了windows的sock api失败
2 和dhcp或者动态dns有关系
3 通过apache的配置来解决
4 php的bug带来的问题
通过一段时间的排查,应该说基本能确认不是前两点问题。那么如何通过配置来解决呢,因为频繁出现的这个问题还导致了apache性能的下降,更不能容忍的是,我们不清楚什么时候apache会出现memory leak。
因此参考了国外网友的经验,在配置文件里面对以下几项开关选项做了设置:
Win32DisableAcceptEx
EnableMMAP Off
EnableSendfile Off
这个方法的处理过程可以参见apache的bug 21425。
问题还没有结束,因为之前配置过Win32DisableAcceptEx开关,打开之后会出现这个问题:
FATAL: erealloc(): Unable to allocate 98304 bytes
如何解决这个问题呢?这里还有解决方法:
将ThreadsPerChild选项从默认的250或者更多,降至170以下。
ThreadsPerChild 170
这样配置之后,这两个问题都不出现了。log里面不再有error和warn了。
最后我还到php的官方buglist里面确认了一下,应该说最新版本的php应该不会出现一些影响apache这个问题的可能。这样,经过下午的观测,到现在为止apache工作还算正常。
我用第一种方法就解决了问题
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫