Tomcat - Tomcat 网络通信模型剖析 并发参数解读
文章目錄
- 什么是IO
- Tomcat 支持四種線程模型
- Tomcat 如何使用指定IO模型
- Tomcat BIO VS NIO
- BIO
- NIO
- 影響 BIO/NIO線程數(shù)量的多少的因素
- Tomcat connector 并發(fā)參數(shù)解讀
什么是IO
IO是指為數(shù)據(jù)傳輸所提供的輸入輸出流,其輸入輸出對象可以是:文件、網(wǎng)絡服務、內存等。
舉個例子,假設應用在從硬盤中讀取一個大文件過程中, CPU會與硬盤一樣出于高負荷狀態(tài)么?
CPU 沒有太高的增漲 。 通常情況下IO操作是比較耗時的,所以為了高效的使用硬件,應用程序可以用一個專門線程進行IO操作,而另外一個線程則利用CPU的空閑去做其它計算。這種為提高應用執(zhí)行效率而采用的IO操作方法即為IO模型。
Tomcat 支持四種線程模型
| BIO | 同步阻塞式IO,即Tomcat使用傳統(tǒng)的java.io進行操作。該模式下每個請求都會創(chuàng)建一個線程,對性能開銷大,不適合高并發(fā)場景。優(yōu)點是穩(wěn)定,適合連接數(shù)目小且固定架構。 |
| NIO | 同步非阻塞式IO,jdk1.4 之后實現(xiàn)的新IO。該模式基于多路復用選擇器監(jiān)測連接狀態(tài)在同步通知線程處理,從而達到非阻塞的目的。比傳統(tǒng)BIO能更好的支持并發(fā)性能。Tomcat 8.0之后默認采用該模式 |
| APR | 全稱是 Apache Portable Runtime/Apache可移植運行庫),是Apache HTTP服務器的支持庫。可以簡單地理解為,Tomcat將以JNI的形式調用Apache HTTP服務器的核心動態(tài)鏈接庫來處理文件讀取或網(wǎng)絡傳輸操作。使用需要編譯安裝APR 庫 |
| AIO (asynchronous I/O) | 異步非阻塞式IO,jdk1.7后之支持 。與nio不同在于不需要多路復用選擇器,而是請求處理線程執(zhí)行完程進行回調調知,已繼續(xù)執(zhí)行后續(xù)操作。Tomcat 8之后支持。 |
Tomcat 如何使用指定IO模型
配置 server.xml 文件當中的 <Connector protocol="HTTP/1.1"> 修改即可。
默認配置 8.0 protocol=“HTTP/1.1” 8.0 之前是 BIO 8.0 之后是NIO
BIO: protocol ="org.apache.coyote.http11.Http11Protocol"
NIO: protocol ="org.apache.coyote.http11.Http11NioProtocol"
AIO: protocol ="org.apache.coyote.http11.Http11Nio2Protocol"
APR: protocol ="org.apache.coyote.http11.Http11AprProtocol"
tomcat 8 以前 默認的是 BIO , 8 默認是 NIO
Tomcat BIO VS NIO
在高并發(fā)場景下BIO與NIO的線程數(shù)的變化
生產環(huán)境上,模擬了處理較慢的過程。
為什么差異這么大呢?
我們先看下這兩種模型的區(qū)別
BIO
源碼翻一翻
我們下個Tomcat 7的版本
https://archive.apache.org/dist/tomcat/tomcat-7/v7.0.99/src/
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />7嘛 ,默認的BIO, 對應的class org.apache.coyote.http11.Http11Protocol.java
看下 Http11Protocol構造函數(shù)
public Http11Protocol() {endpoint = new JIoEndpoint();cHandler = new Http11ConnectionHandler(this);((JIoEndpoint) endpoint).setHandler(cHandler);setSoLinger(Constants.DEFAULT_CONNECTION_LINGER);setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY);}重點 JIoEndpoint ------> Java I/O Endpoint
對應JIoEndpoint 中的
熟悉吧 Socket, 同步阻塞。
繼續(xù)
這個getExecutor()獲取的 就是 那個線程池,用來處理任務的
怎么處理的呢? 繼續(xù)
NIO
老套路
下載 apache-tomcat-8.5.55-src
Http11NioProtocol的構造函數(shù)
重點 NioEndpoint
Acceptor 和 SocketProcessor 大致形同, 主要在于Poller .
先看看Acceptor ,和BIO一樣 ,有點不一樣的是,Acceptor 交個 Poller處理
進入
添加事件
那就看run方法
public void run() {// Loop until destroy() is called 輪詢while (true) {boolean hasEvents = false;try {if (!close) {hasEvents = events();// > 0 說明有socket需要處理if (wakeupCounter.getAndSet(-1) > 0) {//if we are here, means we have other stuff to do//do a non blocking selectkeyCount = selector.selectNow();} else {keyCount = selector.select(selectorTimeout);}wakeupCounter.set(0);}if (close) {events();timeout(0, false);try {selector.close();} catch (IOException ioe) {log.error(sm.getString("endpoint.nio.selectorCloseFail"), ioe);}break;}} catch (Throwable x) {ExceptionUtils.handleThrowable(x);log.error("",x);continue;}//either we timed out or we woke up, process events firstif ( keyCount == 0 ) hasEvents = (hasEvents | events());Iterator<SelectionKey> iterator =keyCount > 0 ? selector.selectedKeys().iterator() : null;// Walk through the collection of ready keys and dispatch// any active event.while (iterator != null && iterator.hasNext()) {SelectionKey sk = iterator.next();NioSocketWrapper attachment = (NioSocketWrapper)sk.attachment();// Attachment may be null if another thread has called// cancelledKey()if (attachment == null) {iterator.remove();} else {iterator.remove();processKey(sk, attachment);}}//while//process timeoutstimeout(keyCount,hasEvents);}//whilegetStopLatch().countDown();}影響 BIO/NIO線程數(shù)量的多少的因素
BIO
- 線程數(shù)量 會受到 客戶端阻塞、網(wǎng)絡延遲、業(yè)務處理慢===>線程數(shù)會更多
NIO
- 線程數(shù)量 會受到業(yè)務處理慢===>線程數(shù)會更多
Tomcat connector 并發(fā)參數(shù)解讀
| acceptCount | 等待最大隊列 |
| address | 綁定客戶端特定地址,127.0.0.1 |
| bufferSize | 每個請求的緩沖區(qū)大小。bufferSize * maxThreads |
| compression | 是否啟用文檔壓縮 |
| compressableMimeTypes | text/html,text/xml,text/plain |
| connectionTimeout | 客戶發(fā)起鏈接 到 服務端接收為止,中間最大的等待時間 |
| connectionUploadTimeout | upload 情況下連接超時時間 |
| disableUploadTimeout | true 則使用connectionTimeout |
| enableLookups | 禁用DNS查詢 true |
| keepAliveTimeout | 當長鏈接閑置 指定時間主動關閉 鏈接 ,前提是客戶端請求頭 帶上這個 head"connection" " keep-alive" |
| maxKeepAliveRequests | 最大的 長連接數(shù) |
| maxHttpHeaderSize | HTTP請求、響應頭信息的最大大小,默認是8192bytes |
| maxSpareThreads | BIO 模式下 最多線閑置線程數(shù) |
| maxThreads | (執(zhí)行線程) 最大執(zhí)行線程數(shù) |
| minSpareThreads | (初始線業(yè)務線程 10) BIO 模式下 最小線閑置線程數(shù) |
總結
以上是生活随笔為你收集整理的Tomcat - Tomcat 网络通信模型剖析 并发参数解读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tomcat - 你该知道的Tomcat
- 下一篇: Tomcat - 都说Tomcat违背了