我使用的是kairosdb最新版本。我试过启用jetty线程池。我的期望是,如果队列大小被请求填充,那么所有后续请求都会立即被拒绝。尽管我看到了,但请求在某个时候才被送达。
java.util.concurrent.RejectedExecutionException如果队列已满,则应拒绝客户端请求。如何实现同样的目标?
为了测试,我添加了这些参数。
kairosdb.jetty.threads.queue_size=2 #queue
kairosdb.jetty.threads.min=2 # minThread
kairosdb.jetty.threads.max=4 #maxThread
kairosdb.jetty.threads.keep_alive_ms=1000对应的jetty线程池代码
new ExecutorThreadPool(minThreads, maxThreads, keepAliveMs, TimeUnit.MILLISECONDS, queue);
在kairosdb中使用的jetty版本是8.1.16。
发布于 2018-11-11 20:00:24
Jetty 8.1.16于2014年9月发布,现在是EOL (寿命结束),考虑使用最新的、稳定的、受支持的Jetty版本。(如Jetty 9.4.12.20180830)
事实上,您得到一个java.util.concurrent.RejectedExecutionException尖叫,您有一个不足的线程池配置。
您所拥有的线程池配置非常小。
这只适用于单核、单cpu、单线程硬件配置。为什么?这是因为cpu/核心/线程硬件配置决定了NIO行为,并规定了线程池的最低要求。
2009年的MacOS笔记本电脑(近10年前!)您需要至少9个线程来支持单个连接,在该硬件上发出单个阻塞REST请求。
在现代Ryzen线程系统上,您通常需要69个线程的最小线程数来支持单个连接,在此硬件上发出单个阻塞REST请求。
另一方面,您的配置非常适合于Raspberry Pi Zero,并且可以支持大约3个连接,每个连接有1个请求活动。
使用该配置,您将只能处理串行的简单请求,并且您的应用程序不使用任何异步处理或异步I/O行为。为什么?这是因为,由于浏览器如何利用服务器,即使是典型的现代网页也需要最少的线程数在40左右。
对于您的情况来说,ExecutorThreadPool也是一个糟糕的选择(这只适用于高度并发的环境,比如24+ cpu/核,最小线程配置在500以上,通常有数千个线程)。
您最好使用标准的QueuedThreadPool,它对于低端来说性能要好得多,并且能够处理需求的增长(并随着时间的推移缩小以降低需求的资源利用率)。
QueuedThreadPool (在Jetty9.4.x中)也有针对不良配置的保护,如果配置不足以满足您的硬件配置、Jetty中选择的一组功能或Jetty中的特定配置,则会警告您。
如果您想在资源不足时拒绝连接,那么请考虑使用DoSFilter (或者如果您希望更温和一些,请考虑使用QoSFilter)。
试图通过ThreadPool限制使用是行不通的,因为为了拒绝连接,需要一个线程来接受它(接受线程,每个服务器连接器一个),另一个线程处理NIO事件(选择器线程,共享资源,处理多个连接),另一个线程处理请求(返回http状态代码503)。
如果您希望在您自己的代码(而不是Jetty)中实现,您可能只需编写一个Filter,它可以计数活动的交换(请求和响应),如果计数高于某个可配置的数字,则强制503响应状态。
但如果你这样做,你可能应该强迫所有的反应关闭。又名Connection: close响应头,不允许持久连接。
https://stackoverflow.com/questions/53252366
复制相似问题