繁体   English   中英

如何使用 Undertow 在 Spring-boot 中取消未完成的、长时间运行的请求?

[英]How to cancel unfinished, long-running requests in Spring-boot with Undertow?

我有一个 Spring-boot 服务,使用 Undertow,其主要客户端是客户端站点上的传感器(约 250 个这样的设备)。 这些传感器每 10 秒通过站点 WiFi 向服务发送 POST 一次——这在某些地方有点参差不齐。 我正在跟踪 NewRelic 中的服务,偶尔会看到长度为 HOURS 的请求响应时间(典型响应时间为几十毫秒)。 在服务的控制器上没有处理 - 所有有效负载都在线程外缓存并通过单独的进程转发。 大约 15 小时左右后,服务停止响应,需要重新启动。 我怀疑这些长时间运行的请求正在使用于处理来自其他传感器的请求的线程池饱和。 NewRelic 建议遇到的所有错误都非常类似于以下内容:

I/O error while reading input message; nested exception is java.io.IOException: 
UT000128: Remote peer closed connection before all data could be read

这些错误中有很大比例的消息提示 Spring-boot JSON 处理器中的异常,这些异常抱怨无效/意外的字符或关闭的输入。

似乎有些传感器正在努力完成它们的 POST。 这是一个公平的解释吗?

有没有办法可以强制我的服务在它们吃掉我的所有处理程序线程之前“终止”这些请求? 我知道客户端断路器可能是处理此问题的最佳方式,但我目前还没有太多控制权。

我也不喜欢把 Undertow 作为一个 Servlet 容器——Tomcat 或 Jetty 对我来说很好,如果它能让这只猫的皮肤更容易一些。

我在@Configuration类中有以下代码:

@Bean
public ServletWebServerFactory servletWebServerFactory() {
    UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(contextPath, serverPort);

    factory.addBuilderCustomizers((builder) -> {
        ...
        builder.setServerOption(UndertowOptions.IDLE_TIMEOUT, 60000);
        ...
    });
    return factory;
}

但它似乎并没有消除请求。

此错误发生在以下场景(B 侧)。

A--呼叫--> B

B服务中总是发生高流量会导致错误。

所以这里的工作

  1. 更高的池设置

server.undertow.worker-threads 300

  1. 限制undowtow的最大连接数,拒绝可以避免更多的损失并保护您的服务。

high_water:默认 1000000 low_water:默认 1000000

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM