0%

tomcat之Connector连接器

Tomcat 之 Connector 连接器深度解析

在 Tomcat 架构中,Connector(连接器) 是负责与客户端通信的核心组件,它封装了底层网络通信细节,为上层容器(Catalina)提供统一的请求入口。本文将详细解析 Connector 的功能、结构及工作原理。

Connector 概述

Connector 是 Tomcat 对外提供服务的接口,基于 Coyote 框架实现,主要功能包括:

  • 网络通信:监听端口,接收客户端连接(如 HTTP 请求)。
  • 协议解析:根据 HTTP、AJP 等协议解析请求数据。
  • 数据转换:将字节流转换为 Tomcat 内部的 Request 对象,再转换为标准的 ServletRequest 供容器处理;处理完成后将响应反向转换为字节流返回客户端。

核心目标:使 Catalina 容器与具体的协议和 I/O 模型解耦,提高灵活性和可扩展性。

支持的协议与 I/O 模型

1. 传输协议

Connector 支持三种主要协议:

协议 用途
HTTP/1.1 最常用协议,用于 Tomcat 独立运行时处理 HTTP 请求。
AJP/1.3 用于与 Web 服务器(如 Apache、Nginx)集成,优化静态资源处理和集群部署。
HTTP/2.0 新一代 HTTP 协议(Tomcat 8.5+ 支持),支持多路复用、服务器推送等特性。

2. I/O 模型

Tomcat 8.5 后移除了对 BIO(阻塞 I/O)的支持,保留以下三种 I/O 模型:

I/O 模型 实现方式 特点
NIO 基于 Java NIO 类库 非阻塞 I/O,通过 Selector 实现多路复用,性能优于 BIO。
NIO2 基于 JDK 7 的 NIO2(AIO) 异步非阻塞 I/O,由操作系统完成 I/O 操作后通知应用程序。
APR 基于 Apache 可移植运行时库(C 实现) 操作系统级别的异步 I/O,性能最优,但需单独安装 APR 库。

Connector 配置示例

Connector 的配置通常在 conf/server.xml 中,以下是一个 HTTP/1.1 协议的 NIO 连接器配置:

1
2
3
4
5
6
7
8
9
10
11
12
<Connector 
port="8080" <!-- 监听端口 -->
protocol="HTTP/1.1" <!-- 协议类型 -->
connectionTimeout="20000" <!-- 连接超时时间(毫秒) -->
redirectPort="8443" <!-- HTTPS 重定向端口 -->
URIEncoding="UTF-8" <!-- URL 编码格式 -->
maxThreads="500" <!-- 最大线程数 -->
minSpareThreads="100" <!-- 最小空闲线程数 -->
acceptCount="200" <!-- 请求队列大小 -->
compression="on" <!-- 启用响应压缩 -->
compressionOnMinSize="10240" <!-- 压缩阈值(字节) -->
/>

关键参数说明

  • maxThreads:处理请求的最大线程数,决定并发处理能力。
  • acceptCount:当所有线程都繁忙时,排队等待的请求数,超过则拒绝连接。
  • connectionTimeout:客户端建立连接后,未发送请求的超时时间。

Connector 内部结构

Connector 的核心结构由三个组件构成,协同完成请求处理:ProtocolHandler、Endpoint、Processor、Adapter

Connector结构

1. ProtocolHandler(协议处理器)

ProtocolHandler 是 Connector 的核心接口,封装了具体协议和 I/O 模型的实现。不同的协议和 I/O 模型对应不同的实现类,例如:

  • Http11NioProtocol:HTTP/1.1 + NIO
  • AjpAprProtocol:AJP/1.3 + APR

作用:协调 Endpoint、Processor 和 Adapter 的工作,是 Connector 的 “总指挥”。

1
2
3
4
5
6
7
8
// Connector 中根据协议选择 ProtocolHandler
public void setProtocol(String protocol) {
if ("HTTP/1.1".equals(protocol)) {
setProtocolHandlerClassName("org.apache.coyote.http11.Http11NioProtocol");
} else if ("AJP/1.3".equals(protocol)) {
setProtocolHandlerClassName("org.apache.coyote.ajp.AjpNioProtocol");
}
}

2. Endpoint(通信端点)

Endpoint 负责底层网络通信,是对传输层(TCP/IP)的抽象。主要功能:

  • 监听端口,接收客户端 Socket 连接。
  • 管理连接的建立与关闭,将字节流传递给 Processor。

实现类

  • NioEndpoint:基于 NIO 的实现。
  • Nio2Endpoint:基于 NIO2 的实现。
  • AprEndpoint:基于 APR 的实现。

核心组件

  • Acceptor:线程,负责监听并接收 Socket 连接,封装为 PollerEvent 放入队列。
  • Poller:线程,通过 Selector 监听 Socket 的 I/O 事件(读 / 写),将就绪的连接交给 SocketProcessor 处理。
  • SocketProcessor: Runnable 任务,由线程池执行,调用 Processor 解析请求。
1
2
3
4
5
6
7
8
9
// Acceptor 接收连接的核心逻辑
public void run() {
while (running) {
SocketChannel socket = serverSock.accept(); // 接收 Socket 连接
if (!setSocketOptions(socket)) { // 配置 Socket 并交给 Poller
closeSocket(socket);
}
}
}

3. Processor(协议处理器)

Processor 负责解析应用层协议(如 HTTP),将字节流转换为 Tomcat 内部的 RequestResponse 对象。

工作流程

  1. 从 Endpoint 获取字节流。
  2. 解析 HTTP 请求行、头信息、体内容。
  3. 生成 org.apache.coyote.Request 对象(Tomcat 内部请求对象)。
  4. 调用 Adapter 将请求提交给容器。

特点:单线程处理,同一次连接复用 Processor 实例。

1
2
3
4
5
6
// Processor 处理请求的核心逻辑
public SocketState process(SocketWrapperBase<?> socketWrapper, SocketEvent status) {
// 解析请求,生成 Tomcat Request
state = service(socketWrapper);
return state;
}

4. Adapter(适配器)

Adapter 负责将 Tomcat 内部的 Request 转换为标准的 ServletRequest,并将请求提交给 Catalina 容器处理。

核心实现CoyoteAdapter,通过调用容器的 Pipeline 触发请求处理链。

1
2
3
4
5
// Adapter 将请求提交给容器
public void service(Request req, Response res) {
// 转换为 ServletRequest/ServletResponse
connector.getService().getContainer().getPipeline().getFirst().invoke(req, res);
}

请求处理流程

Connector 处理一个 HTTP 请求的完整流程如下:

  1. 监听连接Acceptor 线程监听端口,接收客户端 Socket 连接。
  2. 分发连接Poller 线程通过 Selector 检测 Socket 就绪事件,将连接交给 SocketProcessor
  3. 解析请求SocketProcessor 调用 Processor 解析 HTTP 协议,生成 Tomcat Request/Response
  4. 适配请求Adapter 将 Tomcat 请求转换为 ServletRequest,提交给 Catalina 容器。
  5. 处理请求:容器处理请求,生成响应。
  6. 返回响应:响应经 Processor 转换为字节流,通过 Endpoint 发送给客户端

欢迎关注我的其它发布渠道