Tomcat支持三种接收请求的处理方式: BIO
, NIO
, APR
BIO模式: 阻塞式I/O操作,表示Tomcat使用的是传统Java I/O操作(即:java.io包及其子包);Tomcat 7以下版本默认情况下是以BIO模式运行的,由于每个请求的都要创建一个线程来处理,因此 线程的开销较大,不能处理高兵的场景,在三种模式中性能也最低效;启动Tomcat看日志如下表示为BIO模式:
NIO模式: 是Java SE 1.4以后续版本提供的一种新的I/O操作方式(即:java.nio包及其子包);是一个基于 缓存区
、并提供非阻塞I/O操作的Java API,它拥有比传统的I/O操作(BIO)更好的并发运行性能;
APR模式: 简单理解就是,从操作系统级别解决异步IO问题,大幅度的提高服务器的处理合相应性能,也是Tomcat运行高并发应用的首选模式;
官方对三种运行模式的区别说明如下:
参数
Java Blocking Connector (BIO模式)
Java Nio Blocking Connector(NIO模式)
APR/native Connector(APR模式)
classname
AjpProtocol
AjpNioProtocol
AjpAprProtocol
Tomcat Version
3.x onwards
7.x onwards
5.5.x onwards
Support Polling
NO
YES
YES
Polling Size
N/A
maxConnections
maxConnections
Read Request Headers
Blocking
Sim Blocking
Blocking
Read Request Body
Blocking
Sim Blocking
Blocking
Write Response
Blocking
Sim Blocking
Blocking
Wait for next Request
Blocking
Non Blocking
Non Blocking
Max Connections
maxConnections
maxConnections
maxConnections
特征
模式
默认运行版本
处理方式
BIO运行模式
Tomcat7或以下版本
一个线程处理一个请求;缺点:并发量高是,线程数较多,浪费资源
NIO运行模式
Tomcat8版本
利用Java的异步IO处理,可通过少量的线程处理大量请求;
APR运行模式
Tomcat7 或 8 在win7或以上系统中默认使用
从操作系统层面解决IO阻塞问题;
**
Tomcat启动时,可以通过 catalina.out
启动日志查看使用的是哪种运行模式:**
Starting ProtocolHandler ["http-bio-8080"] ## BIO模式
Starting ProtocolHandler ["http-nio-8080"] ## NIO模式
Starting ProtocolHandler ["http-apr-8080"] ## APR模式
Tomcat BIO模式
自Tomcat 8.5 版本开始,Tomcat就移除了对BIO的支持; BIO即阻塞式I/O,是java提供的最基本的I/O方式。在网络通信(此处主要讨论TCP/IP协议)中,需要通过Socket在客户端与服务端建立双向链接以实现通信,主要步骤如下:
(1) 服务端监听某个端口是否有链接请求
(2) 客户端想服务端发出链接请求
(3) 服务端想客户端返回Accept(接受)消息,此时链接成功
(4) 客户端和服务端通过send()、write()等方法与对方通信
(5) 关闭链接
Tomcat 7以下版本默认情况下是以BIO模式运行的,由于每个请求的都要创建一个线程来处理,因此 线程的开销较大,不能处理高并发的场景,在三种模式中性能也最低效;启动Tomcat看日志如下表示为BIO模式:
Tomcat NIO模式
重要提示:使用这些功能需要使用APR或NIO HTTP连接器。传统的java.io HTTP连接器和AJP连接器不支持它们
传统的BIO方式是基于流进行读写的,而且是阻塞的,整体性能比较差; 为了提供I/O性能,JDK自1.4版本引入了NIO模式,它弥补了原来BIO方式的不足,在标准的java代码中提供了 高速、面向块的I/O。 通过定义包含数据的类以及以块的形式处理数据,NIO可以在不编写本地代码的情况下利用底层优化,这是BIO所无法做到的;
NIO模式 是Java SE 1.4及后续版本提供的一种新的I/O操作方式(即java.nio包及其子包)。是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,它拥有比传统I/O操作(bio)更好的并发运行性能。要让Tomcat以nio模式来运行比较简单,只需要在Tomcat安装目录/conf/server.xml文件中将如下配置:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改成:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
注意: Tomcat8以上版本,默认使用的就是NIO模式;不需要额外修改
提示: 更改模式时,如果只修改上述文件内容,则只有 ["http-nio-8180"]
被修改为NIO模式,若想上图中2处都修改为 NIO模式
则还需要修改如下内容:
<Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />
改为:
<Connector port="8109" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443" />
以下属性是特定于NIO连接器 NIO连接器官方详细说明
Tomcat NIO2模式
NIO2是JDK7新增的文件及网络I/O特性,它继承自NIO 同时添加了众多特性及功能改进,其中最重要的即是对异步I/O(AIO)的支持;
1 . 通道 在AIO中,通道必须实现接口
java.nio.chanels.AsynchronousChannel(继承自java.nio.channels.Channel)
JDK7提供了3个通道实现类:java.nio.channels.AsynchronousFileChannel用于文件I/O
,java.nio.channels.AsynchronousServerSocketChannel
和java.nio.channels.AsynchronousSocketChannel用于网络I/O
2 . 缓冲区 AIO仍通过操作缓冲区完成数据的读写操作,这里不再阐述。
3 . Future 和 CompletionHandler AIO操作存在两种操作方式: Future 和 CompletionHandler ; 我们可以使用其中任何一种来完成I/O操作 首先, AIO使用了java并发包的API,无论接收Socket请求还是读写操作,均可以返回一个java.util.concurrent.Future对象来表示I/O处于等待状态; 通过Future的方法,我们可以检测操作是否完成(isDone)、等待完成并取得操作结果(get)等。 当接收请求(accept)结束时,Future.get返回值为AsynchronousSocketChannel; 读写操作时(read/write),Future.get返回值为读写操作结果。
4 . 异步通道组 AIO新引入了异步通道组(Asynchronous Channel Group)的概念,每个异步通道均属于一个指定的异步通道组,同一个通道组内的通道共享一个线程池; 线程池内的线程接收指令来执行I/O事件并将结果分发到CompletionHandler。 异步通道组包括线程池以及所有通道工作线程共享的资源。通道生命周期受所属通道组影响,当通道组关闭后,通道也随之关闭;
Tomcat APR模式
APR模式:简单来说,就是从操作系统级别解决异步IP问题,大幅度的提高服务器的处理和响应性能,也是Tomcat运行高并发应用的首选模式;
启动这种模式需要安装一些依赖库,下面进行详细说明:
基于Apache Portable Runtime(APR)的Tomcat本地库
安装要求:
APR 1.2+开发头文件(libapr1-dev包)
OpenSSL 0.9.7+开发头文件(libssl-dev包)
来自Java兼容JDK 1.4+的JNI头文件
GNU开发环境(gcc,make)
apr的安装
下载apr包地址(http://apache.fayea.com/apr/)
## 下载解压
wget http://apache.fayea.com/apr/apr-1.6.3.tar.gz
wget http://apache.fayea.com/apr/apr-util-1.6.1.tar.gz
tar fxz apr-1.6.3.tar.gz
tar fxz apr-util-1.6.1.tar.gz
## 安装
cd apr-1.6.3/
./configure --prefix=/usr/local/apr
make && make install
cd apr-util-1.6.1/
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
make && make install
安装tomcat-native
cd /usr/local/tomcat/bin tar -zxvf tomcat-native.tar.gz
cd tomcat-native-1.1.22-src/jni/native
./configure --with-apr=/usr/local/apr
make && make install
设置apr环境变量
# vim /etc/profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
# 执行 source /etc/profile 立即生效
修改Tomcat配置文件
修改http协议
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改成:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="20000"
redirectPort="8443" />
修改AJP协议
<Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />
改为:
<Connector port="8109" protocol="org.apache.coyote.http11.Http11AprProtocol" redirectPort="8443" />
总结
对于每种协议,Tomcat都提供了对应的I/O方式的实现,而且Tomcat官方还提供了在每种协议下每种I/O实现方案的差异; HTTP协议下的处理方式如下表:
NIO
NIO2
APR
引用版本
≥6.0
≥8.0
≥5.5
轮询支持
是
是
是
轮询队列大小
maxConnections
maxConnections
maxConnections
读请求头
非阻塞
非阻塞
非阻塞
读请求体
阻塞
阻塞
阻塞
写响应
阻塞
阻塞
阻塞
等待新请求
非阻塞
非阻塞
非阻塞
SSL支持
Java SSL/Open SSL
Java SSL/Open SSL
Open SSL
SSL握手
非阻塞
非阻塞
阻塞
最大链接数
maxConnections
maxConnections
maxConnections
本文分享自微信公众号 - 杰哥的IT之旅(Jake_Internet)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。