ファイルディスクリプタの上限を超えたらTomcatがどうなるか調べてみた

ファイルディスクリプタの上限を超えたらTomcatがどうなるか調べてみた。とりあえずyumコマンドでインストール。

# yum install tomcat5 tomcat5-webapps tomcat5-admin-webapps

こんな感じで、必ず10秒かかっちゃうページを用意した。

<%@ page contentType="text/html;charset=UTF-8" autoFlush="true" %>
<html>
<head>
<title>10</title>
</head>
<body>
<%
for(int i=0;i<=10;i++){
  Thread.sleep(1000);
  out.print("…");
  out.flush();
}
%>
</body>
</html>

Apache Benchで負荷をかける。(同時接続数205)

C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin>ab -c 205 -n 205 http://192.168.159.128:8080/out.jsp

catalina.outにこんな感じのメッセージが出た。

SEVERE: All threads (150) are currently busy, waiting. Increase maxThreads (150) or check the servlet status

server.xmlのmaxThreadsを150から1500に上げたら出なくなった。

# diff -u server.xml_old server.xml
--- server.xml_old      2012-09-20 04:54:41.000000000 -0700
+++ server.xml  2012-09-20 05:00:10.000000000 -0700
@@ -75,7 +75,7 @@

     <!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
     <Connector port="8080" maxHttpHeaderSize="8192"
-               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+               maxThreads="1500" minSpareThreads="25" maxSpareThreads="75"
                enableLookups="false" redirectPort="8443" acceptCount="100"
                connectionTimeout="20000" disableUploadTimeout="true" />

負荷を上げてみる。上限を1500まで上げたので、リクエストを1280件同時に上げる。

C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin>ab -c 1280 -n 1280 http://192.168.159.128:8080/out.jsp
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.159.128 (be patient)
apr_socket_recv: 既存の接続はリモート ホストに強制的に切断されました。   (730054)

こんどは強制的に切断されるようになった。
catalina.outにはこういうメッセージがバンバン出た。

SEVERE: Endpoint ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=8080] ignored exception: java.net.SocketException: Too many open files

ファイルディスクリプタの上限に引っかかってるっぽい。なので、起動スクリプト/etc/init.d/tomcat5を修正してみる。
こんな感じでulimitコマンドを追加したら出なくなった。

# diff -u tomcat5_old tomcat5
--- tomcat5_old 2012-09-20 05:41:00.000000000 -0700
+++ tomcat5     2012-09-20 05:42:45.000000000 -0700
@@ -176,6 +176,7 @@

 # See how we were called.
 function start() {
+    ulimit -n 4096
     echo -n "Starting ${TOMCAT_PROG}: "
     if [ -f "/var/lock/subsys/${NAME}" ] ; then
         if [ -f "/var/run/${NAME}.pid" ]; then

まとめ

Linuxの場合ユーザーごとのファイルディスクリプタの上限のデフォルトは1024みたい。なので、それを超えるリクエストをいっぺんに受けたいときは、ulimitで上限を上げてやる必要がある。