搜索

首页  >  问答  >  正文

java - tomcat不定期close_wait过多

之前使用的是apache-tomcat-7.0.26+jdk1.6.0_31运行很久了,算是正常,因为有时候也会出现close_wait过多问题,大约2-3千吧,然后就自动恢复了。
现在升级版本到apache-tomcat-8.0.9+jdk1.7.0_72运行7-8个小时就要重启,不然就报close_wait超高一万多个,然后就报socket connect timeout,必须重启,时间也不确定就是7-8个小时,有时长点十多个小时,不一定。查看tomcat的catalina.out有大量下面错误:
27-Oct-2015 22:25:33.621 INFO [pool-1300-thread-1] org.apache.coyote.AbstractProcessor.setErrorState An error occurred in processing while on a non-container thread. The connection will be closed immediately
java.io.IOException: APR error: -32

    at org.apache.coyote.http11.InternalAprOutputBuffer.writeToSocket(InternalAprOutputBuffer.java:292)
    at org.apache.coyote.http11.InternalAprOutputBuffer.writeToSocket(InternalAprOutputBuffer.java:245)
    at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(InternalAprOutputBuffer.java:214)
    at org.apache.coyote.http11.AbstractOutputBuffer.flush(AbstractOutputBuffer.java:306)
    at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:763)
    at org.apache.coyote.Response.action(Response.java:177)
    at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:345)
    at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:313)
    at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:110)
    at net.bull.javamelody.FilterServletOutputStream.flush(FilterServletOutputStream.java:52)
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:297)
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
    at java.io.PrintWriter.flush(PrintWriter.java:320)
    at com.iyd.commons.bigpipe.Pagelet.writeValue(Pagelet.java:86)
    at com.iyd.commons.bigpipe.Pagelet.call(Pagelet.java:78)
    at com.iyd.commons.bigpipe.Pagelet.call(Pagelet.java:1)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

不知道是不是和版本升级有关系,请各位达人帮忙看看,非常感谢!

天蓬老师天蓬老师2814 天前883

全部回复(2)我来回复

  • PHP中文网

    PHP中文网2017-04-17 15:30:19

    首先你要知道 close_wait 是什么,这个状态与 time_wait 有一定的相似之处,都会持有这个连接一定的时间不放。我们知道,几乎所有的操作系统对单个进程的句柄数(连接数)都有限制,例如多数 linux 系统默认是 1024 个。

    举例

    1. 某日,你的人品爆发,网站突然来了 1000 个人,那么 tomcat 将消耗 1000 个连接去处理这些请求

    2. 当请求返回后,这 1000 个连接并没有马上销毁,而是全部处于 wait 状态

    3. 这时你的网站又来了 1000 个人(人品持续爆发),但之前那 1000 个连接是无法接受新的请求的(全部处于 wait 状态),所以你现在只有 24 个连接可以使用,so,其他 976 人陷入了漫长的等待中。。。。

    4. 5分钟后,最初的 1000 个连接被逐渐释放了,这时你又有 1000 个连接可以使用了

    5. 无奈那些陷入等待的 976 人已经走的差不多了,就只剩下了 3 个,但是值得高兴的是,因为有了可用连接,他们都可以愉快的连接到你的网站,快乐的玩耍了

    故事讲到这里我想你也明白了是什么导致的问题,是因为那些处于 wait 的连接太多,导致可用连接应接不暇。
    那么,如何优化,答案很简单,禁用 wait ,让连接在返回后立马关闭,成为一个可用连接。

    以 tomcat 为例

    <Connector port="33011" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000" maxThreads="1000" URIEncoding="UTF-8" keepAliveTimeout="0" />

    注意 keepAliveTimeout="0" 即为关键所在,其他 server 都会有相关配置,有兴趣的自己去翻翻文档。

    回复
    0
  • 怪我咯

    怪我咯2017-04-17 15:30:19

    修改系统句柄数限制,并设置系统tcp的超时

    回复
    0
  • 取消回复