默认情况下,Jetty中的线程池在线程池填满后使用无界队列实现。我想限制队列的大小。 BlockingArrayQueue
有一个构造函数,它带有maxCapacity
值但我看不到使用jetty.xml调用它的方法。从Jetty 9开始,org.eclipse.jetty.server.Server
中的线程池没有setter,我只能获得对已经实例化并对其进行变异的线程池的引用(参见this answer)。并且QueuedThreadPool
中队列字段的setter抛出UnsupportedOperationException
,说要使用构造函数注入。但是,如果我只能改变线程池,而不是在服务器实例上设置新线程池,那么这是不可能的。尝试将线程池定义为构造函数arg会产生以下警告:
2014-09-22 13:15:13.688:警告:oejx.XmlConfiguration:main:忽略arg:| 200501000 | 6000 |假|
这是Jetty Maven插件v9.2.2.v20140723。这是我的pom.xml中的配置:
<configuration>
<jettyXml>${basedir}/jetty.xml</jettyXml>
<stopKey>x</stopKey>
<stopPort>7999</stopPort>
<requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
<append>true</append>
</requestLog>
<webApp>
<war>${basedir}/target/app</war>
<contextPath>/app</contextPath>
</webApp>
<scanTargets>
<scanTarget>${basedir}/src/main/webapp/WEB-INF/</scanTarget>
</scanTargets>
<reload>manual</reload>
</configuration>
答案 0 :(得分:3)
更新:不幸的是,服务器构造函数是您配置线程池的方式you cannot configure the Server constructor from within jetty-maven-plugin。这超出了jetty-maven-plugin的范围。
Jetty 9中的ThreadPool现在设置在Constructor of the Server
实例中。
使用XML,您可以重新配置它,甚至documented in the jetty.xml itself。
随意更改它,请注意,如果限制太小,已知绑定线程池会导致问题。
这是一个方便的餐巾配方。
最大线程数=(((cpu核心数)* 4)*(连接器数))+(最大并发请求数)
实际上,大多数低于400的值都会导致即使是温和的服务器也会出现问题。不要将此声明视为意义400是一个很好的起点,这对你来说是非常不合适的,你需要测试,监控并不断调整,直到找到服务器的快乐价值。 (不要忘记测试负载峰值,以及当数据库发生故障时会发生什么)
认为您需要设置性能的上限是premature optimization的一种形式。
Jetty使用的QueuedThreadPool确实是未绑定的,但它也会自行清理并随着时间的推移从池中删除线程,允许服务器处理突然加载并在负载消退时退回。
如果您关注它的内存或其他资源,请知道默认的Jetty安装在Android 2.3(Gingerbread)(注意:Jetty 7 w / QTP),Android 4.4(Jetty 9)和Raspberry Pi(码头7至9)。
最后,如何设置接受队列大小。
配置ServerConnector
(通常位于etc/jetty-http.xml
)
<Set name="acceptQueueSize">40</Set>
默认值为0
,与最低级别的ServerSocketChannel.bind(SocketAddress,int)
来电中的backlog
参数相关。
答案 1 :(得分:2)
我们遇到了类似的问题,我们希望服务器在所有线程忙而不是无限期排队时拒绝请求。
我认为这是一个真正的问题,以下是方法。
由于无法覆盖Jetty Server中的默认池大小或类型。我们编写了一个自定义ServerConnector,您可以在其中设置队列大小或执行者。
jetty.addServerCustomizers((Server server) -> {
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue< (maxQueueSize);
ExecutorService exceutorService =
new ThreadPoolExecutor(minThreads, maxThreads, 1,
TimeUnit.HOURS, queue);
// extract host and port from existing connector...
String host = "0.0.0.0";
int port = 1900;
for (Connector c : server.getConnectors()) {
if (c instanceof ServerConnector) {
host = ((ServerConnector) c).getHost();
port = ((ServerConnector) c).getPort();
}
}
ServerConnector connector = new ServerConnector(server, exceutorService, null, null, -1, -1, new HttpConnectionFactory());
connector.setHost(host);
connector.setPort(port);
server.setConnectors(new Connector[] { connector });
}
1)由于Jetty需要一个Queued线程池,当我们尝试使用它时,它曾经用于提供服务器启动失败的随机结果,尽管配置正确。这种行为是不可预测的。
2)由于ExecutorService没有实现Threadpool,Jetty的metrics集合插件可能无法正常工作。
当我们投入生产时,会更新此答案。