2014-04-29 734 views
7

我想更好地理解Tomcat如何处理请求以及为什么可能会发生特定问题。Tomcat EOFException:在套接字上读取意外的EOF

我想用Netflix Hystrix框架来增强我现有的Spring MVC Web应用程序。这涉及添加hystrix特定的servlet来处理以/hystrix.stream结尾的请求。

根据日志(如下所示),此映射工作并将请求转发到正确的servlet。但是,在servlet中不会发生引发的异常。我也尝试过扩展servlet来添加额外的日志记录 - 但似乎没有调用servlet中的任何方法。这个异常似乎正在发生,因为我不知道Tomcat的内部工作。

这里是我的web.xml片段(请注意,我的应用程序的其余部分工作正常 - 这只是关于为/hystrix.stream请求):

<servlet> 
    <display-name>HystrixMetricsStreamServlet</display-name> 
    <servlet-name>HystrixMetricsStreamServlet</servlet-name> 
    <servlet-class>com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet</servlet-class> 
</servlet> 

<servlet-mapping> 
    <servlet-name>HystrixMetricsStreamServlet</servlet-name> 
    <url-pattern>/hystrix.stream</url-pattern> 
</servlet-mapping> 

当我浏览到loalhost:8080 /web-app/hystrix.stream我被转发到Tomcat 404错误。在tomcat的日志文件中出现以下异常:

2014-04-16 15:53:22 DEBUG AuthenticatorBase:419 - Security checking request GET /web-app/hystrix.stream 
2014-04-16 15:53:22 DEBUG WebappClassLoader:1582 - loadClass(com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet, false) 
2014-04-16 15:53:22 DEBUG WebappClassLoader:1598 - Returning class from cache 
2014-04-16 15:53:22 DEBUG RealmBase:617 - No applicable constraints defined 
2014-04-16 15:53:22 DEBUG AuthenticatorBase:501 - Not subject to any constraint 
2014-04-16 15:53:22 DEBUG [localhost]:449 - Processing ErrorPage[errorCode=404, location=/404.htm] 
2014-04-16 15:53:22 DEBUG Http11Processor:986 - Error parsing HTTP request header 
java.io.EOFException: Unexpected EOF read on the socket 
      at org.apache.coyote.http11.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:99) 
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:952) 
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) 
      at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
      at java.lang.Thread.run(Unknown Source) 

2014-04-16 15:53:22 DEBUG Http11Protocol:645 - Socket: [[email protected]:129bf96a[TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: Socket[addr=/0:0:0:0:0:0:0:1,port=53783,localport=8443]]], Status in: [OPEN_READ], State out: [CLOSED] 
2014-04-16 15:53:22 DEBUG LimitLatch:126 - Counting down[http-bio-8443-exec-1] latch=4 
2014-04-16 15:53:22 DEBUG Http11Processor:986 - Error parsing HTTP request header 
java.io.EOFException: Unexpected EOF read on the socket 
      at org.apache.coyote.http11.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:99) 
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:952) 
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) 
      at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
      at java.lang.Thread.run(Unknown Source) 

有没有人遇到过类似的问题?正如我所提到的,我的应用程序工作正常 - 这仅适用于/hystrix.stream。我使用Chrome Postman插件将Accept和Content-Type = application/json标头添加到请求中 - 都没有成功。据我所知,对这个servlet的请求没有任何标题要求

感谢您的帮助。

+0

我不知道Netflix的豪猪什么,但似乎这个问题是最可能是客户端正在终止连接或发送服务器不理解的东西导致它终止连接。我会从那里开始。 – CodeChimp

+0

在grails项目的日志中获取此信息。一切工作正常,但..... – froderik

回答

1

问题信息很清楚,你的请求头不正确。

 byte chr = 0; 
    do { 

     // Read new bytes if needed 
     if (pos >= lastValid) { 
      if (!fill())//read request content 
       throw new EOFException(sm.getString("iib.eof.error")); 
     } 
     // Set the start time once we start reading data (even if it is 
     // just skipping blank lines) 
     if (request.getStartTime() < 0) { 
      request.setStartTime(System.currentTimeMillis()); 
     } 
     chr = buf[pos++]; 
    } while ((chr == Constants.CR) || (chr == Constants.LF)); 

以上的Tomcat在InternalInputBuffer.parseRequestLine 源代码 - *。第一次在while函数中会读取内容(8 * 1024)。 [通常你的头就不会那么久]


  • *。你读请求的内容后,该代码会检查 '\ r \ n'

  • *的第一个人物造型。所以,如果您的请求的内容将不会包含此charactors,会抛出异常EOF

  • *。那么头文件paser就是faill,所以web容器不知道Servlet方法,所以你的servlet不会被调用。

我认为服务器是好的,问题是出现在Chrome插件邮差,请检查头