Java NIO Channel:Channel 是 Java 中对于打开和某一外部实体(例如硬件设备,文件,网络连接 socket 或者可以执行 IO 操作的某些组件)连接的抽象。Channel 主要是 IO 事件源,所有写入或者读取的数据都必须经过 Channel。对于 NIO 的 Channel,会通过 Selector 来通知事件的就绪(例如读就绪和写就绪),之后通过 Buffer 进行读取或者写入。
XNIO Worker: Worker 是 Java XNIO 框架中的基本网络处理单元,一个 Worker 包含两个不同的线程池类型,分别是:
IO 线程池,主要调用Selector.start()处理对应事件的各种回调,原则上不能处理任何阻塞的任务,因为这样会导致其他连接无法处理。IO 线程池包括两种线程(在 XNIO 框架中,通过设置 WORKER_IO_THREADS 来设置这个线程池大小,默认是一个 CPU 一个 IO 线程):
读线程:处理读事件的回调
写线程:处理写事件的回调
Worker 线程池,处理阻塞的任务,在 Web 服务器的设计中,一般将调用 servlet 任务放到这个线程池执行(在 XNIO 框架中,通过设置 WORKER_TASK_CORE_THREADS 来设置这个线程池大小)
XNIO ChannelListener:ChannelListener 是用来监听处理 Channel 事件的抽象,包括:channel readable, channel writable, channel opened, channel closed, channel bound, channel unbound
Undertow 是基于 XNIO 的 Web 服务容器。在 XNIO 的基础上,增加:
Undertow BufferPool: 如果每次需要 ByteBuffer 的时候都去申请,对于堆内存的 ByteBuffer 需要走 JVM 内存分配流程(TLAB -> 堆),对于直接内存则需要走系统调用,这样效率是很低下的。所以,一般都会引入内存池。在这里就是 BufferPool。目前,UnderTow 中只有一种 DefaultByteBufferPool,其他的实现目前没有用。这个 DefaultByteBufferPool 相对于 netty 的 ByteBufArena 来说,非常简单,类似于 JVM TLAB 的机制(可以参考我的另一系列:全网最硬核 JVM TLAB 分析),但是简化了很多。我们只需要配置 buffer size ,并开启使用直接内存即可。
Undertow Listener: 默认内置有 3 种 Listener ,分别是 HTTP/1.1、AJP 和 HTTP/2 分别对应的 Listener(HTTPS 通过对应的 HTTP Listner 开启 SSL 实现),负责所有请求的解析,将请求解析后包装成为 HttpServerExchange 并交给后续的 Handler 处理。
Undertow Handler: 通过 Handler 处理响应的业务,这样组成一个完整的 Web 服务器。
我们这一节详细介绍了 Undertow 的结构,并且说明了 Undertow 的优点以及让我们比较担心的地方,并且与其他的 Web 容器做了对比。下一节我们将会分析 Undertow 的详细配置。
微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer: