我们有一个在Tomcat7和MySQL5数据库中运行的Struts2 web应用程序。在网站上导航一段时间后,我们得到了一个例外:
java.net.SocketException: Too many open files
如果我们重新启动Tomcat,它会再次工作一段时间,然后问题再次出现。
有人能帮我摆脱这个问题吗?
STACKTRACE:
java.net.SocketException: Too many open files
at java.net.Socket.createImpl(Socket.java:387)
at java.net.Socket.<init>(Socket.java:361)
at java.net.Socket.<init>(Socket.java:208)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:256)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:271)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2771)
at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at org.apache.tomcat.dbcp.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
at org.apache.tomcat.dbcp.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)
at org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1185)
at org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:79)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
套接字连接被视为文件,它们使用文件描述符(FD),这是一种有限的资源。当一个程序(不一定是你的程序,可能只是Tomcat提供了太多连接)在短时间内打开和关闭了太多的连接时,你会得到:
java.net.SocketException:打开的文件太多
这是因为在关闭后,连接可能会在一段时间内处于TIME_WAIT状态(在Linux上为60秒,在Windows上为4分钟),从而保持FD锁定。当你用完FD时,你会得到一个例外,这基本上意味着
在短时间内打开的套接字连接过多
每个操作系统上的限制不同,可以通过命令检查,例如在Unix/Linux上:
ulimit -n
然后简单地提高限制,例如在Unix/Linux上编辑文件
/etc/security/limits.conf
在文件末尾添加以下行:
USR hard nofile 13370
USR soft nofile 13370
将USR
替换为Tomcat使用的用户名,将13370
替换为要设置的新限制。
你可能需要做其他的操作,按照这个问答;如果以上改变还不够的话。
还要记得重新启动。