通过Jetty 9 Maven插件中的jetty.xml设置队列限制

时间:2014-09-19 16:33:07

标签: java jetty maven-jetty-plugin

默认情况下,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>

2 个答案:

答案 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集合插件可能无法正常工作。

当我们投入生产时,会更新此答案。