Tomcat 线程模型详解

Tomcat 作为最常见的 Servlet 容器,在 6.x 版本就支持了 NIO 模式的 Connector 和 Reactor 模式相比有什么特殊之处吗?首先来看下面的表格:

Java Nio Connector NIO Java Nio2 Connector NIO2 APR/native Connector APR
Classname Http11NioProtocol Http11Nio2Protocol Http11AprProtocol
Tomcat Version since 6.0.x since 8.0.x since 5.5.x
Support Polling YES YES YES
Polling Size maxConnections maxConnections maxConnections
Read Request Headers Non Blocking Non Blocking Non Blocking
Read Request Body Blocking Blocking Blocking
Write Response Headers and Body Blocking Blocking Blocking
Wait for next Request Non Blocking Non Blocking Non Blocking
SSL Support Java SSL or OpenSSL Java SSL or OpenSSL OpenSSL
SSL Handshake Non blocking Non blocking Blocking
Max Connections maxConnections maxConnections maxConnections

Reactor模式

标准 I/O 会存在两个阶段:(以 TCP Socket 举例)

  • 数据在内核态和用户态的复制:TCP 协议栈维护着 Send Buffer(发送缓冲区)和 Recv Buffer(接收缓冲区),因此 read/write 都只是将用户态数据复制到内核态的 Socket Buffer(Send/Recv Buffer)。而 Socket Buffer 和网卡之间会通过 DMA 进行数据传输(不占用 CPU)
  • 等待数据就绪:对于 read 操作来说,就绪是指 Recv Buffer 没有可读的数据;而对于 write 操作来说,就绪是指 Send Buffer 已满无法写入

BIO 称为同步阻塞 I/O,它在上述的两个阶段均会阻塞。因此 BIO 必须为每个 TCP 连接创建新线程并阻塞等待其可读或可写。服务端若想支持大量客户端连接,在 BIO 的前提下使用多线程来解决是必然的事情,下面用一个简单的例子展示:

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×