Undertow HTTP2:请求线程耗尽,线程陷入 org.xnio.conduits...awaitReadable/Writable 操作

问题描述 投票:0回答:2

一天内 5 个可用实例中的一个随机实例偶尔会发生几次情况。工作线程被卡住,在耗尽所有工作线程后,服务无法响应运行状况检查并重新启动。 我们观察到 POST/PUT/PATCH 请求出现问题。 这些被卡住的请求运行数十分钟,然后报告为失败,状态代码为 400 || 500。 阻塞的线程增长很快,几分钟之内就会耗尽所有池,并且它们仅在单个实例上增长,其他 4 个线程运行良好。

Spring启动版本3.1.4 / 3.0.11 Spring Cloud Gateway。(Netty)<->(http2 SSL)带有 REST 端点的基于 Spring 的服务(Undertow)。

我们添加一个 Undertow StuckThreadDetector,它会报告如下堆栈跟踪:

java.lang.Throwable: null
    at [email protected]/java.lang.Object.wait(Native Method)
    at [email protected]/java.lang.Object.wait(Object.java:338)
    at io.undertow.server.protocol.framed.AbstractFramedStreamSourceChannel.awaitReadable(AbstractFramedStreamSourceChannel.java:354)
    at org.xnio.conduits.StreamSourceChannelWrappingConduit.awaitReadable(StreamSourceChannelWrappingConduit.java:71)
    at org.xnio.conduits.ConduitStreamSourceChannel.awaitReadable(ConduitStreamSourceChannel.java:151)
    at io.undertow.channels.DetachableStreamSourceChannel.awaitReadable(DetachableStreamSourceChannel.java:77)
    at io.undertow.server.HttpServerExchange$ReadDispatchChannel.awaitReadable(HttpServerExchange.java:2305)
    at org.xnio.channels.Channels.readBlocking(Channels.java:345)
    at io.undertow.servlet.spec.ServletInputStreamImpl.readIntoBuffer(ServletInputStreamImpl.java:201)
    at io.undertow.servlet.spec.ServletInputStreamImpl.read(ServletInputStreamImpl.java:176)
    at io.undertow.servlet.spec.ServletInputStreamImpl.read(ServletInputStreamImpl.java:162)
    at io.undertow.servlet.spec.ServletInputStreamImpl.read(ServletInputStreamImpl.java:153)
    at [email protected]/java.io.FilterInputStream.read(FilterInputStream.java:82)
    at [email protected]/java.io.PushbackInputStream.read(PushbackInputStream.java:135)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver$EmptyBodyCheckingHttpInputMessage.<init>(AbstractMessageConverterMethodArgumentResolver.java:331)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:172)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:163)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:136)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)

java.lang.Throwable: null
    at java.lang.Object.wait(Object.java)
    at io.undertow.server.protocol.framed.AbstractFramedStreamSinkChannel.awaitWritable(AbstractFramedStreamSinkChannel.java:329)
    at io.undertow.server.protocol.framed.AbstractFramedStreamSinkChannel.awaitWritable(AbstractFramedStreamSinkChannel.java:313)
    at org.xnio.conduits.StreamSinkChannelWrappingConduit.awaitWritable(StreamSinkChannelWrappingConduit.java:99)
    at org.xnio.conduits.ConduitStreamSinkChannel.awaitWritable(ConduitStreamSinkChannel.java:134)
    at io.undertow.channels.DetachableStreamSinkChannel.awaitWritable(DetachableStreamSinkChannel.java:87)
    at io.undertow.server.HttpServerExchange$WriteDispatchChannel.awaitWritable(HttpServerExchange.java:2141)
    // ... 183 frames truncated

这家伙提到了类似的问题https://access.redhat.com/solutions/6988036。 - 但没有任何信息他们如何修复它。

我们添加一个 Undertow StuckThreadDetector 来捕获线程的堆栈跟踪。 当 undertow waitReadable/awaitWritable 出现问题时,我们将尝试使用 BlockingReadTimeoutHandler BlockingWriteTimeoutHandler 快速失败,但我们仍在寻找此类随机问题的根本原因。

java spring http2 undertow
2个回答
2
投票

同样的错误,希望尽快找到解决方案


1
投票

Ohhh...Underthow 的这个棘手问题...当我使用 Tomcat 作为应用程序服务器时 - 没有问题,但是有必要将其更改为 Underthow...

希望您能找到解决方案!

© www.soinside.com 2019 - 2024. All rights reserved.