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