1

我想将 Tomcat 调整为快速失败,以防在所有线程都被占用时出现任何问题(例如,如果数据库突然开始表现不佳,则等待数据库连接)。

我查了几篇文章,特别是: https ://netflixtechblog.com/tuning-tomcat-for-a-high-throughput-fail-fast-system-e4d7b2fc163f https://tomcat.apache.org/tomcat-8.5-doc/配置/http.html

我有几个问题,如果你能帮助我,我将不胜感激:

  1. 为什么 Netflix 将并发请求保留在内存中,如果达到阈值,则在他们自己的代码中回复 503?它自己做的背后的理由是什么?据我从tomcat文档(见上面的链接)了解到,如果达到maxThreads和acceptCount,tomcat会自己回复Connection Refused。因此,正确指定小的 acceptCount 应该是诀窍。

来自 Tomcat 文档:

每个传入的请求在该请求期间都需要一个线程。如果收到的并发请求多于当前可用的请求处理线程可以处理的数量,则将创建额外的线程,直至配置的最大值(maxThreads 属性的值)。如果接收到更多的同时请求,它们会堆积在连接器创建的服务器套接字中,直到配置的最大值(acceptCount 属性的值)。任何进一步的并发请求都将收到“连接被拒绝”错误,直到有可用资源来处理它们。

来自文章:

跟踪内存中活动并发请求的数量并将其用于快速失败。如果并发请求的数量接近估计的活动线程(在我们的示例中为 8),则返回 http 状态代码 503。这将防止过多的工作线程变得忙碌,因为一旦达到峰值吞吐量,任何额外的线程变得活跃将做一个非常轻量级的返回 503 的工作,然后可用于进一步处理。

  1. 我假设即使在 Tomcat NIO 中,工作线程也不会像在 NodeJS 中那样“同时”重复使用。对于一个 http 请求,有一个分配的 1 个工作线程,它不会处理任何其他 http 请求,除非完成这个请求。即使这个 http 请求正在等待像数据库读取这样的阻塞 i/o。

  2. 鉴于上述所有情况,我相信这可能是正确的配置:

# not using the executor, but a 'default' internal thread pool of the connector

maxConnections = -1 # For NIO/NIO2 only, setting the value to -1, will disable the maxConnections feature and connections will not be counted.
# or we can leave default, i.e. 10k. The thing is that only 1 thread ( hence little resources used ) will keep these connections alive, so we can use keepAlive
# and avoid establishing connections again and again which can be costly and resource consuming.

server.tomcat.max-threads = 96 # we assume that 8 cores can handle up to this amount of threads, given that each thread spends significant time in database and/or other network calls
# in the article above it was stated that they increased maxThreads 3 times than the amount of cores

server.tomcat.accept-count = ?? # from one point of view, it can be something really-really small like 16 or 32
# from another point of view, maybe something like 512 
# imagine that due to a temporary network glitch an upstream service won't be reachable and we need few seconds to reach the timeouts and open circuit breaker. would be nice to queue other requests and successfully ( the ones what are independent ) process them seconds after rather than reject them right away

PS 我正在使用 Tomcat 8.5 和 NIO 连接器。

任何帮助/建议将不胜感激。

4

0 回答 0