JBOSS 挂在 org.apache.jk.common.JkInputStream.receive() - 读取 HTTP 请求 InputStream 时出现 IOException

发布于 2024-08-13 22:23:35 字数 2365 浏览 10 评论 0原文

我遇到一个问题,导致 JBOSS 中的所有线程在读取输入流时阻塞。它的发生是不可预测的,系统可能会运行数天(或更长时间),然后才会开始受到影响。

该问题看起来与 this 问题类似,但我尚未尝试设置 -Dhttp.keepAlive=false按照答案中的建议,因为我想知道是否其他人有不同/更好的解决方案。我宁愿不必通过将此属性设置为 false 来招致性能损失(假设甚至可以解决问题)。

有一些 Sun bug 涉及 BufferedReaderInputStream 读取问题 (错误 6192696错误 6409506),但对我来说,它们似乎有点不确定。欢迎您对此类问题和 Sun bug 提出想法/建议/经验。

下面是例外情况:

java.io.IOException
    at org.apache.jk.common.JkInputStream.receive(JkInputStream.java:190)
    at org.apache.jk.common.JkInputStream.refillReadBuffer(JkInputStream.java:249)
    at org.apache.jk.common.JkInputStream.doRead(JkInputStream.java:168)
    at org.apache.coyote.Request.doRead(Request.java:418)
    at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:284)
    at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:404)
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:299)
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:192)
    at com.vicinity.ExtractMessageServlet.service(ExtractMessageServlet.java:62)
    ...

这是请求标头的示例:

POST http: //www.xyz.com HTTP/1.0
Host: www.xyz.com:80
Accept: */*
Content-Type: application/octet-stream
Content-Length: 00597
Session-Key: 812a0000

这是 Web 应用程序的 Servlet 代码。它卡在 servletInputStream.read 上:

int lengthOfBuffer = request.getContentLength();
byte[] buffer = new byte[lengthOfBuffer];
ByteArrayOutputStream output = new ByteArrayOutputStream(lengthOfBuffer);
ServletInputStream servletInputStream = request.getInputStream();
int readBytes = -1;
while ((readBytes = servletInputStream.read(buffer, 0, lengthOfBuffer)) != -1) {
    output.write(buffer, 0, readBytes);
}
byte[] inputStream = output.toByteArray();
...
// Continue to process the input stream

JBoss 版本:JBoss AS 4.0.5.GA。
此外,mod_jk 正在端口 80 上将 HTTP 请求从 Apache 服务器路由到 JBoss 服务器 - 如果您对此感兴趣的话。

I have a problem that causes all threads in JBOSS to block while reading the input stream. It does not happen predictably and the system can run for days (or longer) before it starts to suffer.

The problem looks similar to this question, but I have yet to try setting -Dhttp.keepAlive=false as recommended in the answer because I wondered if anyone else has a different/better solution. I would rather not have to incur a performance hit by setting this property to false (assuming that even fixes the problem).

There are some Sun bugs that talk about issues with BufferedReader and InputStream reading (bug 6192696, bug 6409506), but to me they seem a bit inconclusive. Your thoughts/advice/experience with an issue like this and the Sun bugs would be welcome.

Here is the Exception:

java.io.IOException
    at org.apache.jk.common.JkInputStream.receive(JkInputStream.java:190)
    at org.apache.jk.common.JkInputStream.refillReadBuffer(JkInputStream.java:249)
    at org.apache.jk.common.JkInputStream.doRead(JkInputStream.java:168)
    at org.apache.coyote.Request.doRead(Request.java:418)
    at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:284)
    at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:404)
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:299)
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:192)
    at com.vicinity.ExtractMessageServlet.service(ExtractMessageServlet.java:62)
    ...

Here is a sample of the request headers:

POST http: //www.xyz.com HTTP/1.0
Host: www.xyz.com:80
Accept: */*
Content-Type: application/octet-stream
Content-Length: 00597
Session-Key: 812a0000

Here is the Servlet code of the web application. It get's stuck on servletInputStream.read:

int lengthOfBuffer = request.getContentLength();
byte[] buffer = new byte[lengthOfBuffer];
ByteArrayOutputStream output = new ByteArrayOutputStream(lengthOfBuffer);
ServletInputStream servletInputStream = request.getInputStream();
int readBytes = -1;
while ((readBytes = servletInputStream.read(buffer, 0, lengthOfBuffer)) != -1) {
    output.write(buffer, 0, readBytes);
}
byte[] inputStream = output.toByteArray();
...
// Continue to process the input stream

JBoss version: JBoss AS 4.0.5.GA.
Also, mod_jk is routing HTTP requests on port 80 from Apache server to the JBoss server - if that's of interest.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鹿港巷口少年归 2024-08-20 22:23:35

如果从底层 TCP 套接字读取时出现问题,JkInputStream.receive 将抛出无消息 IOException,不幸的是没有指定发生了什么问题。如果启用 org.apache 包的所有日志级别并检查抛出异常之前记录的内容,您可能会找到有关问题原因的更多详细信息。

JkInputStream.receive will throw a message-less IOException if something went wrong when reading from the underlying TCP socket, unfortunately without specifying what went wrong. You may find more details on the problem cause if you enable all log levels for the org.apache package and check what is logged just before the exception is thrown.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文