查看原文
其他

Tomcat的三种运行模式

Nicholas 杰哥的IT之旅 2019-05-08

Tomcat支持三种接收请求的处理方式: BIONIOAPR

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模式)
classnameAjpProtocolAjpNioProtocolAjpAprProtocol
Tomcat Version3.x onwards7.x onwards5.5.x onwards
Support PollingNOYESYES
Polling SizeN/AmaxConnectionsmaxConnections
Read Request HeadersBlockingSim BlockingBlocking
Read Request BodyBlockingSim BlockingBlocking
Write ResponseBlockingSim BlockingBlocking
Wait for next RequestBlockingNon BlockingNon Blocking
Max ConnectionsmaxConnectionsmaxConnectionsmaxConnections

特征 

模式默认运行版本处理方式
BIO运行模式Tomcat7或以下版本一个线程处理一个请求;缺点:并发量高是,线程数较多,浪费资源
NIO运行模式Tomcat8版本利用Java的异步IO处理,可通过少量的线程处理大量请求;
APR运行模式Tomcat7 或 8 在win7或以上系统中默认使用从操作系统层面解决IO阻塞问题;


Tomcat启动时,可以通过 catalina.out启动日志查看使用的是哪种运行模式:

  1. Starting ProtocolHandler ["http-bio-8080"] ## BIO模式

  2. Starting ProtocolHandler ["http-nio-8080"] ## NIO模式

  3. 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文件中将如下配置:

  1. <Connector port="8080" protocol="HTTP/1.1"

  2. connectionTimeout="20000"

  3. redirectPort="8443" />

修改成:

  1. <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"

  2. connectionTimeout="20000"

  3. redirectPort="8443" />

注意: Tomcat8以上版本,默认使用的就是NIO模式;不需要额外修改

提示: 更改模式时,如果只修改上述文件内容,则只有 ["http-nio-8180"]被修改为NIO模式,若想上图中2处都修改为 NIO模式则还需要修改如下内容:

  1. <Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />

改为:

  1. <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/)

  1. ## 下载解压

  2. wget http://apache.fayea.com/apr/apr-1.6.3.tar.gz

  3. wget http://apache.fayea.com/apr/apr-util-1.6.1.tar.gz

  4. tar fxz apr-1.6.3.tar.gz

  5. tar fxz apr-util-1.6.1.tar.gz

  6. ## 安装

  7. cd apr-1.6.3/

  8. ./configure --prefix=/usr/local/apr

  9. make && make install

  10. cd apr-util-1.6.1/

  11. ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr

  12. make && make install

安装tomcat-native

  1. cd /usr/local/tomcat/bin tar -zxvf tomcat-native.tar.gz

  2. cd tomcat-native-1.1.22-src/jni/native

  3. ./configure --with-apr=/usr/local/apr

  4. make && make install

设置apr环境变量

  1. # vim /etc/profile

  2. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib

  3. # 执行 source /etc/profile 立即生效

修改Tomcat配置文件

修改http协议

  1. <Connector port="8080" protocol="HTTP/1.1"

  2. connectionTimeout="20000"

  3. redirectPort="8443" />

修改成:

  1. <Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"

  2. connectionTimeout="20000"

  3. redirectPort="8443" />

修改AJP协议

  1. <Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />

改为:

  1. <Connector port="8109" protocol="org.apache.coyote.http11.Http11AprProtocol" redirectPort="8443" />

总结

对于每种协议,Tomcat都提供了对应的I/O方式的实现,而且Tomcat官方还提供了在每种协议下每种I/O实现方案的差异; HTTP协议下的处理方式如下表:


NIONIO2APR
引用版本≥6.0≥8.0≥5.5
轮询支持
轮询队列大小maxConnectionsmaxConnectionsmaxConnections
读请求头非阻塞非阻塞非阻塞
读请求体阻塞阻塞阻塞
写响应阻塞阻塞阻塞
等待新请求非阻塞非阻塞非阻塞
SSL支持Java SSL/Open SSLJava SSL/Open SSLOpen SSL
SSL握手非阻塞非阻塞阻塞
最大链接数maxConnectionsmaxConnectionsmaxConnections


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存