ローカルPCに開発用サーバー環境を作ろうと、Windows7 に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

Window's mpm_winnt interprets the AcceptFilter to toggle the AcceptEx() API, and does not support http protocol buffering. There are two values which utilize the Windows AcceptEx() API and will recycle network sockets between connections.data waits until data has been transmitted as documented above, and the initial data buffer and network endpoint addresses are all retrieved from the single AcceptEx() invocation. 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.

Apache MPM winnt
Win32DisableAcceptEx is no longer supported in apache 2.4
use the following instead:
AcceptFilter http none
AcceptFilter https none

※ Win32DisableAcceptEx はApache2.2までで、2.4ではサポートされない。

 

AcceptEx function

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.

結局、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
AcceptFilter http none
AcceptFilter https none
EnableSendfile off
EnableMMAP off
</IfModule>

※ そういえば、Apache2.2のころ、EnableSendfile EnableMMAP をOFFにしないとパフォーマンスが悪い問題があった。

 

とりあえず、この設定でApacheが停止する問題は回避できているようだ。