我在micronaut中实现了一些REST端点(服务A)。端点之一使用java.net.http.HttpRequest
调用另一服务(服务X)。服务X的响应时间可能很长,例如分钟。进行此调用后,我会定期调用服务A(从curl调用),偶尔会挂起。
我测试过将我的服务A称为curl。对我来说,一旦服务A进入对服务X的调用,它就持有nioEventLoopGroup-1-x
线程之一,等待阻塞操作完成。对服务A终结点的后续调用将由不同的nioEventLoopGroup-1-#
线程以循环方式处理。但是一旦阻塞nioEventLoopGroup-1-x
可以转弯,该请求就会挂起。此行为是确定性的,从日志中看到哪个nio线程正在处理请求,我看到当阻塞的线程轮到时,对服务A的调用只是挂起。然后,我向服务A发出新请求,该请求将得到完美响应。如果给定的网络线程池大小为5并且1个网络处理器线程被阻止,那么我将每隔5个请求就挂起A服务。
我认为Micronaut永远不要尝试将HTTP请求处理分配给被阻塞的线程,但显然这正在发生。
有人对如何克服这个问题有任何建议吗?
[在io.micronaut.http.filter.HttpServerFilter
中发现阻止操作将阻止Netty事件循环,并且将出现我上面描述的症状,即被阻止的Netty处理程序将变得无响应。