Node.js と IIS で BROKEN_PIPE 発生から HTTP Keep Alive にたどり着く

自社サービスのログを解析していたときに、以下のようなログに出会いました。サービス自体は稼働していて、たまに引っかかっているようです。

C:\>logparser "select * from *.log where sc-status=500" -i:iisw3c -o:datagrid

注目箇所は以下

  • 画像ファイルのようにプログラムではないもので500エラーになっている
  • 応答コードが500.1013で、Winエラー109「BROKEN_PIPE」エラー

今回は特に「BROKEN_PIPE」が手掛かりでした。

パイプはプロセス間で通信する手段で、コマンドプロンプトでも使われています。

例)dirで出したファイルの一覧をsortで整列、パイプ「|」で連結

dir /b | sort

「iis nodejs broken_pipe」で検索すると英語の掲示板が引っかかりました。

その中で「disable http-keep-alive」とありました。

Node.jsでHTTP-Keep-Alive対応されたのがバージョン8で、そこから5秒のキープアライブ時間が既定値になりました。

ところがNode.jsをホストしているiisnodeがHTTP-Keep-Aliveに対応しておらず、パイプの接続ロストが発生、サーバーエラーになったと推測しました。

createServerしている箇所について、以下の設定を追加してHTTP-Keep-Aliveを無効化すればOKです。

var server = HTTP.createServer(app);
server.keepAliveTimeout = 0;
server.listen(...);

HTTP-Keep-Alive対応されたら解除することにしましょう。