【问题标题】:Undertow blocking operations with dispatch is not working带调度的 Undertow 阻塞操作不起作用
【发布时间】:2017-11-19 20:06:30
【问题描述】:

我无法让最基本的 Undertow 示例按预期工作。以下代码应允许提供并发 HTTP 请求。实际发生的情况是,只有一个请求被处理,在第一个请求完成之前没有其他请求可以通过。

public class MainUT {

    public static void main(String[] args) {
        Undertow.builder()                                                      
            .addHttpListener(8080, "localhost")                                    
            .setHandler(new HttpHandler() {                                                   
                @Override
                public void handleRequest(final HttpServerExchange exchange) 
                                            throws Exception {
                    if(exchange.isInIoThread()){
                        exchange.dispatch(this);
                        return;
                    }
                    exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                    exchange.getResponseSender().send("Hello World");               
                }
            }).build().start();
    }
}

我错过了什么?

我使用 Chrome 发出 GET 请求,并在请求发出后暂停了调试器。然后发出curl命令

 curl http://localhost:8080

curl 命令仅在 Chrome 请求完成后返回。

我在HTTPHTTPS 听众上测试了这一点。

增加 XNIO 线程数和它们的工作线程不会改变任何事情。一个随机 XNIO 被分配给该请求。然后在调度后分配一个随机工人。在请求得到处理之前,服务器会一直处于阻塞状态。

【问题讨论】:

  • 您的代码看起来不错。有什么错误吗?行为?你是怎么测试的?你的 HTTP 客户端是什么?
  • 没有错误。从 Chrome 发出 GET 请求时,它会阻止任何其他请求,直到完成。
  • 您的浏览器是否繁忙?您的并发请求如何?
  • 您应该尝试JMeter 来测试它的并发请求。因为,浏览器一次只发送一个请求。您不能从浏览器发送多个请求。
  • @frhack:不客气!不过,它需要一些澄清。使用一个浏览器tab,您只能发送一个请求。如果服务器可以同时处理多个请求,您可以打开另一个选项卡并发出另一个请求。鉴于 OP 正在手动对其进行测试,并且您一次可以点击一个 URL。希望考虑到这里的完整上下文,这将是有意义的。

标签: undertow


【解决方案1】:

您的代码看起来不错,但查看 BlockingHandler 尝试以下操作或直接使用 BlockingHandler。

exchange.startBlocking();
if (exchange.isInIoThread()) {
    exchange.dispatch(handler);
} else {
    handler.handleRequest(exchange);
}

有关链接 HttpHandler 的简单方法,请查看 MiddlewareBuilder。我还会尝试设置访问日志记录处理程序,以便您可以查看发生了什么以及哪个线程正在处理每个请求。

【讨论】:

  • 嗨,比尔,感谢您的回答。我已经尝试过BlockingHandler 效果不佳。我可以看到请求由另一个线程处理,但整个服务器无法接受更多请求。我会听从你的其他建议。
  • 你能给出一个不工作的确切例子吗?您是否使用睡眠或类似的方式进行测试?
  • 如果您在 IDE 中使用调试器,它不会同时暂停两个线程吗?让您认为它正在等待,但实际上两个线程都刚刚到达调试语句。
  • 不工作的确切例子是问题中的那个。我将使用屏幕截图更新问题,显示在第一个请求被提供之前如何阻止请求
  • 即使不使用阻塞处理程序,undertow 也会运行多个 IO 线程,因此您应该能够一次处理至少 2-4 个请求。似乎调试器出了点问题。
猜你喜欢
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多