5. Tomcat 中的 NIO 应用

本文介绍了Tomcat服务器的核心架构及NIO应用配置与设计。详细解释了Tomcat如何利用NIO提高线程利用率,包括Acceptor接收连接及Poller进行事件迭代等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

5. Tomcat 中的 NIO 应用

  • 5.1. Tomcat 核心架构


Tomcat 是一个 apache 推出的一个 web 应用服务器,核心功能就是解析 Http协议,处理网络 IO 操作,执行 Servlet 对象,其简易架构如下:

其中:

  • 1) Server:代表整个容器,它可能包含一个或多个 Service 和全局的对象资源;
  • 2) Service:包含一个或多个 Connector 和一个 Engine,这些 Connector和 Engine 相关联;
  • 3) Connector:处理与客户端的通信,网络 I/O 操作;
  • 4) Engine:表示请求处理流水线(pipeline),它接收所有连接器的请求,并将响应交给适当的连接器返回给客户端;
  • 5) Host:网络名称(域名)与 Tomcat 服务器的关联,默认主机名 localhost,一个 Engine 可包含多个 Host;
  • 6) Context:表示一个 Web 应用程序,一个 Host 包含多个上下文。

 

  • 5.2. Tomcat 中的 NIO 应用配置


Tomcat 中的 NIO 应用要从 Connector 说起,Connector 是请求接收环节与请求处理环节的连接器。具体点说,就是 Connector 将接收到的请求传递给Tomcat 引擎(Engine)进行处理,引擎处理完成以后会交给 Connector 将其响应到客户端。但是 Connector 本身并不会读写网络中的数据,读写网络中的数据还是要基于网络 IO 进行实现。但使用哪种 IO 模型需要由 Connector 对象进
行指定。
例如:可在 tomcat 的 server.xml 进行配置,其默认配置如下:

<Connector connectionTimeout="20000"
port="8080"
protocol="HTTP/1.1"
redirectPort="8443"/>

一个 Tomcat 中可以配置多个 Connector,分别用于监听不同端口,或处理不同协议,在如上配置中 Connector 使用的协议默认为”HTTP/1.1”,系统底层会基于此配置,通过反射创建 Http11NioProtocol 对象,而此对象底层就是基于NIO 中的 IO 多路复用技术实现网路数据读写的。假如希望使用其它协议或 NIO方式可以修改其默认配置。例如:我们配置 NIO 中的异步应用模型。

<Connector connectionTimeout="20000"
port="8080"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
redirectPort="8443"/>
  • 5.3. Tomcat 中的 NIO 应用设计


在 tomcat 中,目前 IO 模型的最佳应用模式还是 IO 多路复用,因为 BIO 的缺点在于不管当前连接有没有数据传输,它始终阻塞占用线程池内的一个线程,而NIO 的处理方式是若通道无数据可读取,此时线程不阻塞直接返回,可用于处理其他连接,提高了线程利用率。其工作模型大致如下:

  • 1) Acceptor 以阻塞模式接收 TCP 连接,然后对连接信息进行封装并以事件方式注册(register)到 Poller 上;
  • 2) Poller 进行事件迭代,循环执行 selector.select(xxx),如果有通道readable,那么在 processKey 方法中交给 worker 线程池中的线程处理。

说明:假如想在 maven 项目中想对 tomcat 的源码进行快速分析,可先添加如下依赖,基于此依赖可借助 maven 对 tomcat 源码进行组织。

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>9.0.6</version>
</dependency>

基于 tomcat 依赖编写如下代码启动 tomcat,进行 debug 分析

public static void main(String[] args)throws Exception {
    //1.构建tomcat对象
    Tomcat tomcat = new Tomcat();
    //2.构建connector对象,并指定协议
    //tomcat实用connector处理链接,一个tomcat可以配置多个connector
    Connector connector = new Connector("HTTP/1.1");
    //3.设置tomcat舰艇端口
    connector.setPort(8080);
    tomcat.setConnector(connector);
    //启动tomcat
    tomcat.start();
    tomcat.getServer().await();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值