搜尋

首頁  >  問答  >  主體

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)

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

天蓬老师天蓬老师2805 天前862

全部回覆(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
  • 取消回覆