第 10 章 Undertow
10.1. Undertow 处理程序简介
Undertow 是一种 Web 服务器,设计用于阻塞和非阻塞任务。它取代了 JBoss EAP 7 中的 JBoss Web。它的一些主要功能是:
- high performance
- 可嵌入
- Servlet 4.0
- WebSockets
- 反向代理
请求生命周期
客户端连接到服务器时,Undertow 会创建 a io.undertow.server.HttpServerConnection
。当客户端发送请求时,它将由 Undertow 解析器解析,然后生成的 io.undertow.server.HttpServerExchange
传递到 root 处理程序。当 root 处理程序完成后,可能会出现以下四种情况之一:
交易完成。
如果请求和响应通道已完全读取或写入,则交易被视为已完成。对于没有内容的请求,如 GET 和 HEAD,请求方将自动视为完全读取。当处理程序写出完整响应并且关闭并完全清空响应通道时,读取端被视为已完成。如果交换已完成,则不执行任何操作。
root 处理程序通常返回而不完成交换。
在这种情况下,交换是通过调用
HttpServerExchange.endExchange()
来完成的。root 处理程序返回一个例外。
在本例中,设置了
500
的响应代码,并使用HttpServerExchange.endExchange()
结束交换。root 处理程序可以在
HttpServerExchange.dispatch()
被调用后返回,或者在同步 IO 启动后返回。在这种情况下,分配的任务将提交到分配执行器,或者如果在请求或响应通道上启动了异步 IO,则会启动此操作。在这两种情况下,交换都不会完成。处理完后,将由您的 async 任务来完成交换。
目前,最常用的 HttpServerExchange.dispatch()
是从不允许阻止操作的 IO 线程中执行,变为 worker 线程,这确实允许阻止操作。
示例: Dispatching to a Worker Thread
public void handleRequest(final HttpServerExchange exchange) throws Exception { if (exchange.isInIoThread()) { exchange.dispatch(this); return; } //handler code }
由于在调用堆栈返回后实际不会分配交换,您可以确保一次在交换中不再激活多个线程。交换是不安全的。但是,只要两个线程都不会尝试一次修改它,就可以在多个线程之间传递它。
结束 Exchange
有两种方法可以结束交换:完全读取请求频道并在响应频道中调用 shutdownWrites()
,然后清除它,或者调用 HttpServerExchange.endExchange()。
调用 endExchange()
时,Undertow 将检查内容是否已生成。如果存在,它将只排空请求频道并关闭并清空响应频道。如果没有,且在交换上注册了任何默认响应监听器,则 Undertow 将获得生成默认响应的机会。这种机制是生成默认错误页面的方式。
有关配置 Undertow 的更多信息,请参阅 JBoss EAP 配置指南中的配置 Web 服务器。