java - Tomcat EOFException : Unexpected EOF read on the socket 异常

标签 java tomcat spring-mvc servlets

我想更好地了解 Tomcat 如何处理请求以及为什么会出现我的特定问题。

我正在尝试使用 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: [org.apache.tomcat.util.net.SocketWrapper@56a7cbf2: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 header 添加到请求中 - 均未成功。据我所知,对该 servlet 的请求没有任何 header 要求

感谢您的帮助。

最佳答案

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

        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'的第一个字符

  • >*。所以如果你的请求内容不包含这个字符,将抛出 EOF 异常

  • >*。那么 header paser 是失败的,所以 web 容器不知道 Servlet 方法,所以你的 servlet 不会被调用。

我认为服务器没问题,问题出现在Chrome Postman插件中,请检查标题

关于java - Tomcat EOFException : Unexpected EOF read on the socket 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23359727/

相关文章:

eclipse - 使用 Tomcat 和 Eclipse 开发 Portlet

java - spring 应用程序未在对象上找到属性

java - Spring Security部署错误

Java,将null分配给对象和仅声明有什么区别

java - 在 Java 中实例化 MVC 对象时处理依赖关系

java - tomcat共享库-(配置)文件上下文规则

java - 我可以在同一台机器上运行两个 tomcat 实例吗?

java - 在 jetty 和 tomcat 上运行 spring hibernate web 应用程序

java | Gson |将 JSON 对象添加到现有的 JSON 文件

java - 如何在 Java 中将 ZonedDateTime 转换为毫秒?