0

我正在尝试为 undertow 服务器创建多个工作线程,以便多个线程可用于同时处理来自客户端的请求。我尝试使用 UndertowOptions 和 Options 在服务器级别设置它们。尝试创建自定义 XnioWorker 并分配给 Undertow Server。

这里似乎没有任何效果,所有尝试配置工作线程。

Xnio xnio = Xnio.getInstance();
        XnioWorker worker = null;
        try {
            worker = xnio.createWorker(
                    OptionMap.builder().set(Options.WORKER_IO_THREADS, 50).set(Options.WORKER_TASK_CORE_THREADS, 50)
                            .set(Options.WORKER_TASK_MAX_THREADS, 50).set(Options.TCP_NODELAY, true).getMap());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
//      OptionMap socketOptions = OptionMap.builder().set(Options.WORKER_IO_THREADS, 10).set(Options.TCP_NODELAY, true)
//              .set(Options.REUSE_ADDRESSES, true).getMap();

        Undertow server = Undertow.builder().setServerOption(UndertowOptions.ENABLE_HTTP2, true)
                .setServerOption(UndertowOptions.HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
                        UndertowHttp2ServerEpLevel.maxReqPerConn)
                .setServerOption(UndertowOptions.MAX_CONCURRENT_REQUESTS_PER_CONNECTION,
                        UndertowHttp2ServerEpLevel.maxReqPerConn)
                .addHttpListener(port, host)
                .setWorkerOption(Options.WORKER_IO_THREADS, 10)
                .setWorkerOption(Options.WORKER_TASK_CORE_THREADS, 10)
                .setWorkerThreads(UndertowHttp2ServerEpLevel.iotheads)
                .setIoThreads(UndertowHttp2ServerEpLevel.iotheads)
                .setWorker(worker)
                .setHandler(exchange -> {

                    Thread.sleep(responseDelayInMs);

                    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                    Date date = new Date();

                    System.out.print(dateFormat.format(date) + ", **Thread name: " + Thread.currentThread().getName());**
                    System.out.println(
                            ": " + port + ", Client address is: " + exchange.getConnection().getPeerAddress().toString()
                                    + " TotalMsgReceived: " + ++msgCounter);

                    exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
                    exchange.setStatusCode(returnCode);
//                  exchange.getResponseSender().send("Undertow Hi");
               
                }).build();
        server.start();

使用上面的代码,我看到处理程序代码总是由同一个线程执行。假设一个线程的 n/w 延迟为 100 毫秒,我每秒只能处理 9 个请求。这就是为什么我希望更多数量的线程同时处理请求,以便实现高速率。

控制台输出:

*2021/07/29 09:22:46,线程名称:XNIO-1 I/O-12:8081,客户端地址:/127.0.0.1:16002 TotalMsgReceived:534

2021/07/29 09:22:47,线程名称:XNIO-1 I/O-12:8081,客户端地址为:/127.0.0.1:16002 TotalMsgReceived:535*

现在从 JMX 我看到线程池大小已更新为 50,但性能仍然没有改善,并且在控制台中没有看到多工作线程: 在此处输入图像描述

对此的任何看法都会有所帮助。谢谢!

4

2 回答 2

1

From the documentation

Dispatching to a worker thread

public void handleRequest(final HttpServerExchange exchange) throws Exception{
    if (exchange.isInIoThread()) {
      exchange.dispatch(this);
      return;
    }
    //handler code
}

You seem to be missing this part, because everything in your case is running on IO thread.

There are multiple overloads of dispatch method that you can choose from depending on your use case.

于 2021-07-29T05:28:37.293 回答
0

以下代码完成了这项工作。

Undertow server = Undertow.builder().setServerOption(UndertowOptions.ENABLE_HTTP2, true)
                .setServerOption(UndertowOptions.HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
                        UndertowHttp2ServerEpLevelMT.maxReqPerConn)
                .setServerOption(UndertowOptions.MAX_CONCURRENT_REQUESTS_PER_CONNECTION,
                        UndertowHttp2ServerEpLevelMT.maxReqPerConn)
                .addHttpListener(port, host)
                .setWorkerOption(Options.WORKER_IO_THREADS, UndertowHttp2ServerEpLevelMT.iotheads)
                .setWorkerOption(Options.WORKER_TASK_CORE_THREADS, UndertowHttp2ServerEpLevelMT.iotheads)
                .setWorkerOption(Options.WORKER_TASK_MAX_THREADS, UndertowHttp2ServerEpLevelMT.iotheads)
                .setWorkerThreads(UndertowHttp2ServerEpLevelMT.iotheads)
                .setIoThreads(UndertowHttp2ServerEpLevelMT.iotheads)
                .setHandler(new HttpHandler() {
                    @Override
                    public void handleRequest(final HttpServerExchange exchange) throws Exception {
                        if (exchange.isInIoThread()) {
                            exchange.dispatch(this);
                            return;
                        }
                        System.out.println("Port: " + port + ", Client address is: "
                                + exchange.getConnection().getPeerAddress().toString());
                        exchange.setStatusCode(returnCode);
                    }
                }).build();
        server.start();
于 2021-07-29T13:52:21.203 回答