无法使用 Jetty 服务器线程池最大大小限制并发请求,为什么?

Cannot limit concurrent request with Jetty Server Thread Pool max size, why?

我创建了一个带线程池的 Jetty 服务器来限制对服务器的并发请求数。但是我指定的大小我可以提出的总请求总是比我指定的大小小5。

依赖关系:

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>9.4.6.v20170531</version>
</dependency>

服务器代码:

public void httpServer(int port, Handler handler, String name) {
    QueuedThreadPool threadPool = new QueuedThreadPool(10);
    Server server = new Server(threadPool);
    server.setHandler(handler);
    HttpConfiguration http = new HttpConfiguration();

    ServerConnector serverConnector = new ServerConnector(server, new HttpConnectionFactory(http));
    serverConnector.setPort(port);
    server.setConnectors(new Connector[]{serverConnector});

    try {
        log.info(name + " Listener Started on port: " + port);
        server.start();
        server.join();
    } catch (Exception e) {
        log.error("Unable to start Server... Exiting");
        log.error(e, e);
        System.exit(1);
    }
}

处理程序:

public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) {
    try {

        BufferedReader bufferedReader = request.getReader();
        String s;
        StringBuilder sb = new StringBuilder();
        PrintWriter writer = response.getWriter();
        while ((s = bufferedReader.readLine()) != null) {
            sb.append(s);
        }
        System.out.println("Got Request");
        Thread.sleep(2000);
        response.setStatus(HttpServletResponse.SC_OK);
        baseRequest.setHandled(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

在上面的代码中,指定的线程池大小是 10。但同时我只能做 5。我尝试将大小更改为 20,但在那种情况下,我可以做的并发请求总是少 5,即15. 知道这 5 个线程在哪里使用吗?

Jetty 不是那样工作的。

线程池不是那样工作的。

Jetty ThreadPool 用于任何需要线程的事情,而不仅仅是请求。

包括:

  • 低级网络
  • nio 选择器
  • 网络接受者
  • http 会话维护
  • 部署管理器行为
  • 与凭证提供者合作
  • 内部 http 客户端行为
  • 已分派内部请求
  • 异步处理行为
  • http/2 主连接处理(将协议泵送到每个 http/2 session/stream)
  • osgi模块解析
  • 文件系统监控
  • 超时
  • 注解/字节码扫描
  • 代理行为
  • 等...

对线程池的需求会根据您使用的功能(servlet、字节码扫描、代理、fastcgi 等)、您使用的技术(例如:http/2、websocket、unixsockets 等)而变化,甚至你的机器有多大(你的机器拥有的核心数量,nio 本身会根据你的机器拥有的核心数量的子集需要线程)。

还有一个 "Reserved Threads" 切片从任何提供的线程池中取出来处理对服务器上的操作至关重要的事情。保留线程的需求在运行时可能会发生变化(如上所述,它还取决于所使用的技术)

如果您想限制正在处理的请求的数量,请使用针对您想要限制的 url 模式配置的 QoSFilter。 (或者如果您的要求略有不同,请使用 DoSFilter

不要通过线程池执行此操作,那是永远不会工作的。