Apache HTTP Server(Windows)が応答しなくなる。

ローカルPCに開発用サーバー環境を作ろうと、Windows 7 にApache HTTP Server 2.4系をインストールした。
IEでhttp://localhost/hogehoge.pdf を別TABでたくさん開いてみた。
すると、何個目からか応答が返ってこず、IEは受信中のようになる。
しばらく待っていると、応答が返ってくることがある。

この状態になると、ChromeやFireFoxなど別のブラウザでアクセスしても応答が返ってこない。

SysinternalsSuiteのTcpview.exeで見てみると、たくさんのEstablishedコネクションがあり、TCPは接続できているように見える。

だが応答が来ないようだ。

この状態で別のPCのブラウザで接続してみると応答は返ってきた。

IEで多量にアクセスした場合のみ発生する。

C:\Apache24\bin>httpd -V
Server version: Apache/2.4.16 (Win32)
Apache Lounge VC11 Server built:   Jul 12 2015 10:56:48
Server's Module Magic Number: 20120211:47
Server loaded:  APR 1.5.2, APR-UTIL 1.5.4
Compiled using: APR 1.5.2, APR-UTIL 1.5.4
Architecture:   32-bit
Server MPM:     WinNT
  threaded:     yes (fixed thread count)
    forked:     no
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses disabled)
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/apache"
 -D SUEXEC_BIN="/apache/bin/suexec"
 -D DEFAULT_PIDLOG="logs/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error.log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

なにか特定クライアントからの同時アクセスを制限するディレクティブでもあるのかと思ったが、apacheのエラーログを眺めていてやっと原因がわかった。

[Thu Jul 30 16:50:33.222571 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:33.223072 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:33.223072 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:33.223072 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:33.223072 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:33.223072 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:33.223072 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:33.223572 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:33.223572 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:41.154790 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:41.155291 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:41.155291 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.
[Thu Jul 30 16:50:41.155291 2015] [mpm_winnt:warn] [pid 10940:tid 1920] (OS 64)指定されたネットワーク名は利用できません。  : AH00341: winnt_accept: Asynchronous AcceptEx failed.

AH00341: winnt_accept: Asynchronous AcceptEx failed.を調べてみると、Apacheにこういう設定が必要らしい。
参考となったサイトは次の通り。

httpd.confに必要な設定

Be sure you have in httpd.conf:

For 2.2: Win32DisableAcceptEx EnableSendfile off EnableMMAP off

For 2.4: AcceptFilter http none AcceptFilter https none EnableSendfile off EnableMMAP off

Apache :: Apache 2.4 Problems in Windows x86

Window’s mpm_winnt interprets the AcceptFilter to toggle the AcceptEx() API, and does not support http protocol buffering. connect will use the AcceptEx() API, also retrieve the network endpoint addresses, but like none the connect option does not wait for the initial data transmission. On Windows, none uses accept() rather than AcceptEx() and will not recycle sockets between connections. This is useful for network adapters with broken driver support, as well as some virtual network providers such as vpn drivers, or spam, virus or spyware filters. core - Apache HTTP Server Version 2.4

By default, this MPM uses advanced Windows APIs for accepting new client connections. In some configurations, third-party products may interfere with this implementation, with the following messages written to the web server log: Child: Encountered too many AcceptEx faults accepting client connections. winnt_mpm: falling back to ‘AcceptFilter none’. The MPM falls back to a safer implementation, but some client requests were not processed correctly. In order to avoid this error, use AcceptFilter with accept filter none. AcceptFilter http none AcceptFilter https none In Apache httpd 2.0 and 2.2, Win32DisableAcceptEx was used for this purpose. mpm_winnt - Apache HTTP Server Version 2.4

The AcceptEx function accepts a new connection, returns the local and remote address, and receives the first block of data sent by the client application. AcceptEx function (mswsock.h) - Win32 apps | Microsoft Docs

結局、C:\Apache24\conf\httpd.conf に以下の設定を追加した。

  • C:\Apache24\conf\httpd.conf
# Server-pool management (MPM specific)
#Include conf/extra/httpd-mpm.conf
Include conf/extra/httpd-mpm.conf

※httpd-mpm.confを有効にする。 C:\Apache24\conf\extra\httpd-mpm.conf mpm_winnt_moduleにAcceptFilter ~EnableMMAP を追加。

# WinNT MPM
# ThreadsPerChild: constant number of worker threads in the server process
# MaxConnectionsPerChild: maximum number of connections a server process serves
<IfModule mpm_winnt_module>
    ThreadsPerChild        150
    MaxConnectionsPerChild   0
<strong class="red">AcceptFilter http none
AcceptFilter https none
EnableSendfile off
EnableMMAP off</strong>
</IfModule>

※ そういえば、Apache2.2のころ、EnableSendfile EnableMMAP をOFFにしないとパフォーマンスが悪い問題があった。 とりあえず、この設定でApacheが停止する問題は回避できているようだ。