1.問題出現
昨晚項目在上線的時候因為推廣的原因,新增的大量請求。在八點的時候。
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:356) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:825) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:730) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:391) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:369) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at com.fasterxml.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:2085) ~[jackson-core-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.core.json.UTF8JsonGenerator._writeStringSegment2(UTF8JsonGenerator.java:1400) ~[jackson-core-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.core.json.UTF8JsonGenerator._writeStringSegment(UTF8JsonGenerator.java:1347) ~[jackson-core-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.core.json.UTF8JsonGenerator._writeStringSegments(UTF8JsonGenerator.java:1228) ~[jackson-core-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.core.json.UTF8JsonGenerator.writeString(UTF8JsonGenerator.java:453) ~[jackson-core-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.std.StringSerializer.serialize(StringSerializer.java:41) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396) ~[jackson-databind-2.9.5.jar!/:2.9.5] at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913) ~[jackson-databind-2.9.5.jar!/:2.9.5] at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:286) ~[spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:102) ~[spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:272) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:180) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) ~[spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158) [spring-boot-actuator-2.0.2.RELEASE.jar!/:2.0.2.RELEASE] at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126) [spring-boot-actuator-2.0.2.RELEASE.jar!/:2.0.2.RELEASE] at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111) [spring-boot-actuator-2.0.2.RELEASE.jar!/:2.0.2.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123) [druid-1.1.10.jar!/:1.1.10] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:84) [spring-boot-actuator-2.0.2.RELEASE.jar!/:2.0.2.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter.doFilter(ExceptionLoggingFilter.java:48) [spring-cloud-sleuth-core-2.0.1.RELEASE.jar!/:2.0.1.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at brave.servlet.TracingFilter.doFilter(TracingFilter.java:86) [brave-instrumentation-servlet-5.1.4.jar!/:na] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.6.RELEASE.jar!/:5.0.6.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_172] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_172] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.31.jar!/:8.5.31] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_172] Caused by: java.io.IOException: Broken pipe at sun.nio.ch.FileDispatcherImpl.write0(Native Method) ~[na:1.8.0_172] at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) ~[na:1.8.0_172] at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) ~[na:1.8.0_172] at sun.nio.ch.IOUtil.write(IOUtil.java:65) ~[na:1.8.0_172] at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471) ~[na:1.8.0_172] at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:134) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:157) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1276) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:670) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:450) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:388) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:623) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:123) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:225) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.coyote.Response.doWrite(Response.java:541) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:351) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31] ... 99 common frames omitted
百度之后最簡單解釋:
一、Broken pipe產生原因分析
1.當訪問某個服務突然服務器掛了,就會產生Broken pipe;
2.客戶端讀取超時關閉了連接,這時服務器往客戶端再寫數據就發生了broken pipe異常!
二、方案
1.問題一分析服務器為什么掛了。
2.問題二使用jps/jstack分析線程棧,看是不是有線程阻塞。
其實就是服務器扛不住請求了,所以把日志級別先調整到error然后項目重啟。問題解決。
2.來看看專業人員的解釋。
今天公司技術支持的童鞋報告一個客戶的服務不工作了,緊急求助,於是遠程登陸上服務器排查問題。
查看采集數據的tomcat日志,習慣性的先翻到日志的最后去查看有沒有異常的打印,果然發現了好幾種異常信息,但是最多還是這個:
-
24-Nov-2016 09:54:21.116 SEVERE [http-nio-8081-Acceptor-0] org.apache.tomcat.util.net.NioEndpoint$Acceptor.run Socket accept failed
-
java.io.IOException: Too many open files
-
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
-
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java: 241)
-
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java: 688)
-
at java.lang.Thread.run(Thread.java: 745)
“Too manay open files” 問題很明顯啊,文件描述符超出限制導致無法打開文件或創建網絡連接,這個問題又會導致一些其它問題的產生,肯定是ulimit沒有優化,於是檢查ulimit的設置;
-
[root@sdfassd logs] # ulimit -a
-
core file size (blocks, -c) 0
-
data seg size (kbytes, -d) unlimited
-
scheduling priority (-e) 0
-
file size (blocks, -f) unlimited
-
pending signals (-i) 62819
-
max locked memory (kbytes, -l) 64
-
max memory size (kbytes, - m) unlimited
-
open files (-n) 65535
-
pipe size (512 bytes, -p) 8
-
POSIX message queues (bytes, - q) 819200
-
real- time priority (-r) 0
-
stack size (kbytes, - s) 10240
-
cpu time (seconds, -t) unlimited
-
max user processes (-u) 62819
-
virtual memory (kbytes, -v) unlimited
-
file locks (- x) unlimited
open files竟然是65535,已經做過了優化,是不是先啟動的tomcat等服務,然后才對ulimit做的優化?有可能,這樣的話重啟一下服務就ok了,於是將全部服務重啟了一遍,運行正常了,不一會報表就顯示數據了,然后告訴技術支持,問題已經解決了,然后就去處理別的case了;
結果還不到20分鍾,技術支持說,報表又沒有數據了,於是又打數據采集的應用的tomcat日志查看,發現了一堆異常,全都是一個錯:
-
24-Nov-2016 09:54:24.574 WARNING [http-nio-18088-exec-699] org.apache.catalina.core.StandardHostValve.throwable Exception Processing ErrorPage[exceptionType=java.lang.Throwable, location=/views/error/500.jsp]
-
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
-
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java: 393)
-
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java: 426)
-
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java: 342)
-
at org.apache.catalina.connector.OutputBuffer.close(OutputBuffer.java: 295)
-
at org.apache.catalina.connector.Response.finishResponse(Response.java: 453)
-
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java: 378)
-
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java: 174)
-
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java: 79)
-
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java: 610)
-
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java: 610)
-
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java: 88)
-
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java: 537)
-
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java: 1085)
-
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java: 658)
-
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java: 222)
-
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java: 1556)
-
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java: 1513)
-
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java: 1142)
-
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java: 617)
-
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java: 61)
-
at java.lang.Thread.run(Thread.java: 745)
這個異常非常多,看報錯信息,是tomcat的connector在執行寫操作的時候發生了Broken pipe異常,connector是tomcat處理網絡請求的,難道是網絡出問題了,但是為什么發生異常的都是寫,讀就沒問題呢?為了判斷是不是網絡問題,於是用wget命令在本地訪問了一下服務器的一個接口,結果發現等了好久都沒有響應,正常情況下應該是馬上就有響應的,這說明不是網絡的原因,是服務器的問題,又用命令查看了下當前tcpip連接的狀態:
-
[root@sdfassd logs]# netstat -n | awk '/^tcp/ {++state[$ NF]} END {for(key in state) print key,"\t",state[key]}'
-
CLOSE_WAIT 3853
-
TIME_WAIT 40
-
ESTABLISHED 285
-
LAST_ACT 6
CLOSE_WAIT 狀態的連接竟然有3853個,這太不正常了,這說明是客戶端先關閉了連接,服務器端沒有執行關閉連接的操作,導致服務器端一直維持在CLOSE_WAIT的狀態,如果不對操作系統的keepalive做優化,這個狀態默認會維持兩個小時,查看了下系統的設置:
-
[root@sdfassd logs] # sysctl -a |grep keepalive
-
net.ipv4.tcp_keepalive_time = 7200
-
net.ipv4.tcp_keepalive_probes = 9
-
net.ipv4.tcp_keepalive_intvl = 75
果然是7200秒,這就解釋通了,為什么第一次查看tomcat日志最后報錯都是“Too manay open files”異常,一定是在兩個小時內,close_wait狀態暴增,導致文件描述符超過了65535的最大限制;
而這個狀態應該就是broken pipe 異常導致的,是什么導致的broken pipe異常呢?為什么探針關閉了連接,但是數據采集服務器卻沒有關閉連接?報異常的是tomcat的connector,tomcat不可能會忘記調用close方法去關閉連接,排除了程序的問題,也想不出來是什么導致的了;
於是去拿了往采集服務器上傳數據的探針的日志查看,竟然有大量的一個異常:
-
2016 -11-24 16:27:36,217 [TingYun Harvest Service 1] 166 WARN - Error occurred sending metric data to TingYun. There can be intermittent connection failures. Please wait for a short period of time: java.net.SocketTimeoutException: Read timed out
-
java.net.SocketTimeoutException: Read timed out
-
at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.7.0_60]
-
at java.net.SocketInputStream.read(SocketInputStream.java:152) ~[na:1.7.0_60]
-
at java.net.SocketInputStream.read(SocketInputStream.java:122) ~[na:1.7.0_60]
-
at com.tingyun.agent.libs.org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SourceFile:136) ~[tingyun-agent-java.jar:2.1.3]
-
.................
都是read time out異常,那么問題就明確了, 是探針端讀取超時了,斷開了連接,而這時候數據采集服務器還在處理請求,它並不知道探針端已經斷開了連接,處理完請求后再將處理結果發給探針,就broken pipe了;
原來這個異常是客戶端讀取超時關閉了連接,這時候服務器端再向客戶端已經斷開的連接寫數據時就發生了broken pipe異常!
探針讀超時的時間是2分鍾,服務器為什么這么長的時間都沒有響應呢?於是使用jstack命令導出了tomcat的線程棧信息進行分析,最后發現代碼中有耗時的操作加了鎖,導致線程阻塞(保密原因,在這里就不貼代碼了);
這里總結一下,給我發私信的有些朋友沒有get到Broken piple問題的重點,並不是只有超時才會導致這個問題,只要是連接斷開,再往這個斷開的連接上去執行寫操作,都會出現這個異常,客戶端超時斷開只是其中的一種情況:
另外,當看到“Too manay open files”異常的時候,通常做法除了檢查ulimit系統限制外,還應該看一下進程打開的文件句柄數,cat /proc/sys/fs/file-nr命令查看系統總句柄數,當前應用打開的文件句柄數使用ls -l /proc/<pid>/fd | wc -l命令,這里還好忽略了這一步,否則可能又要花費一些時間來查找系統真正的問題;
通過這個案例可知,排查問題時,在有些情況下,你第一眼看到的異常信息未必就是問題的根源所在,而是后續一些連鎖反應,尤其是當大量出現同一個異常的情況下,不要看最后一條異常日志,應該先去日志里面查找第一出現該異常的位置,看看這個異常發生之前系統的狀況;
java tcp/ip異常
- 1 java.net.SocketTimeoutException .
這 個異 常比較常見,socket 超時。一般有 2 個地方會拋出這個,一個是 connect 的 時 候 , 這 個 超 時 參 數 由connect(SocketAddress endpoint,int timeout) 中的后者來決定,還有就是 setSoTimeout(int timeout),這個是設定讀取的超時時間。它們設置成 0 均表示無限大。
- 2 java.net.BindException:Address already in use: JVM_Bind
該 異 常 發 生 在 服 務 器 端 進 行 new ServerSocket(port) 或者 socket.bind(SocketAddress bindpoint)操作時。
原因:與 port 一樣的一個端口已經被啟動,並進行監聽。此時用 netstat –an 命令,可以看到一個 Listending 狀態的端口。只需要找一個沒有被占用的端口就能解決這個問題。
- 3 java.net.ConnectException: Connection refused: connect
該異常發生在客戶端進行 new Socket(ip, port)或者 socket.connect(address,timeout)操作時,原 因:指定 ip 地址的機器不能找到(也就是說從當前機器不存在到指定 ip 路由),或者是該 ip 存在,但找不到指定的端口進行監聽。應該首先檢查客戶端的 ip 和 port是否寫錯了,假如正確則從客戶端 ping 一下服務器看是否能 ping 通,假如能 ping 通(服務服務器端把 ping 禁掉則需要另外的辦法),則 看在服務器端的監聽指定端口的程序是否啟動。
- 4 java.net.SocketException: Socket is closed
該異常在客戶端和服務器均可能發生。異常的原因是己方主動關閉了連接后(調用了 Socket 的 close 方法)再對網絡連接進行讀寫操作。
- 5 java.net.SocketException: Connection reset 或者Connect reset by peer:Socket write error
該異常在客戶端和服務器端均有可能發生,引起該異常的原因有兩個,第一個就是假如一端的 Socket 被關閉(或主動關閉或者因為異常退出而引起的關閉), 另一端仍發送數據,發送的第一個數據包引發該異常(Connect reset by peer)。另一個是一端退出,但退出時並未關閉該連接,另 一 端 假 如 在 從 連 接 中 讀 數 據 則 拋 出 該 異 常(Connection reset)。簡單的說就是在連接斷開后的讀和寫操作引起的。
還有一種情況,如果一端發送RST數據包中斷了TCP連接,另外一端也會出現這個異常,如果是tomcat,異常如下:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
阿里的tcp方式的健康檢查為了提高性能,省去揮手交互,直接發送一個RST來終斷連接,就會導致服務器端出現這個異常;
對於服務器,一般的原因可以認為:
a) 服務器的並發連接數超過了其承載量,服務器會將其中一些連接主動 Down 掉.
b) 在數據傳輸的過程中,瀏覽器或者接收客戶端關閉了,而服務端還在向客戶端發送數據。
- 6 java.net.SocketException: Broken pipe
該異常在客戶端和服務器均有可能發生。在拋出SocketExcepton:Connect reset by peer:Socket write error 后,假如再繼續寫數據則拋出該異常。前兩個異常的解決方法是首先確保程序退出前關閉所有的網絡連接,其次是要檢測對方的關閉連接操作,發現對方 關閉連接后自己也要關閉該連接。
對於 4 和 5 這兩種情況的異常,需要特別注意連接的維護。在短連接情況下還好,如果是長連接情況,對於連接狀態的維護不當,則非常容易出現異常。基本上對長連接需要做的就是:
a) 檢測對方的主動斷連(對方調用了 Socket 的 close 方法)。因為對方主動斷連,另一方如果在進行讀操作,則此時的返回值是-1。所以一旦檢測到對方斷連,則主動關閉己方的連接(調用 Socket 的 close 方法)。
b) 檢測對方的宕機、異常退出及網絡不通,一般做法都是心跳檢測。雙方周期性的發送數據給對方,同時也從對方接收“心跳數據”,如果連續幾個周期都沒有收到 對方心跳,則可以判斷對方或者宕機或者異常退出或者網絡不通,此時也需要主動關閉己方連接;如果是客戶端可在延遲一定時間后重新發起連接。雖然 Socket 有一個keep alive 選項來維護連接,如果用該選項,一般需要兩個小時才能發現對方的宕機、異常退出及網絡不通。
- 7 java.net.SocketException: Too many open files
原因: 操作系統的中打開文件的最大句柄數受限所致,常常發生在很多個並發用戶訪問服務器的時候。因為為了執行每個用戶的應用服務器都要加載很多文件(new 一個socket 就需要一個文件句柄),這就會導致打開文件的句柄的缺乏。
解決方式:
a) 盡量把類打成 jar 包,因為一個 jar 包只消耗一個文件句柄,如果不打包,一個類就消耗一個文件句柄。
b) java 的 GC 不能關閉網絡連接打開的文件句柄,如果沒有執行 close()則文件句柄將一直存在,而不能被關閉。
也可以考慮設置 socket 的最大打開 數來控制這個問題。對操作系統做相關的設置,增加最大文件句柄數量。
ulimit -a 可以查看系統目前資源限制,ulimit -n 10240 則可以修改,這個修改只對當前窗口有效。
- 8 Cannot assign requested address
1. 端口號被占用,導致地址無法綁定:
java.net.BindException: Cannot assign requested address: bind:是由於IP地址變化導致的;
2. 服務器網絡配置異常:
/etc/hosts 中配置的地址錯誤;
3.還有一種情況是執行ipconfig 發現沒有環路地址,這是因為環路地址配置文件丟失了;、
--------------------- 作者:朱清震 來源:CSDN 原文:https://blog.csdn.net/zqz_zqz/article/details/52235479
轉載引用 ------------https://www.cnblogs.com/jiangds/p/6848529.html