Tomcat支持三种接收请求的处理方式: BIO
, NIO
, APR
java
BIO模式: 阻塞式I/O操做,表示Tomcat使用的是传统Java I/O操做(即:java.io包及其子包);Tomcat 7如下版本默认状况下是以BIO模式运行的,因为每一个请求的都要建立一个线程来处理,所以 线程的开销较大,不能处理高并的场景,在三种模式中性能也最低效;启动Tomcat看日志以下表示为BIO模式:apache
NIO模式: 是Java SE 1.4之后续版本提供的一种新的I/O操做方式(即:java.nio包及其子包);是一个基于 缓存区
、并提供非阻塞I/O操做的Java API,它拥有比传统的I/O操做(BIO)更好的并发运行性能;vim
APR模式: 简单理解就是,从操做系统级别解决异步IO问题,大幅度的提升服务器的处理合相应性能,也是Tomcat运行高并发应用的首选模式;缓存
官方对三种运行模式的区别说明以下: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
启动日志查看使用的是哪一种运行模式:网络
自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模式:
重要提示:使用这些功能须要使用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链接器官方详细说明
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。 异步通道组包括线程池以及全部通道工做线程共享的资源。通道生命周期受所属通道组影响,当通道组关闭后,通道也随之关闭;
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包地址(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
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
# vim /etc/profile ,# vim /etc/profileexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib# 执行 source /etc/profile 当即生效
修改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 |
参考连接 :
Tomcat的三种运行模式 : https://mp.weixin.qq.com/s/SI3RlSYxdE12N27sRcnahg