Tomcat學習之線程模型(三)

種類

tomcat一共有四種線程模型,以下:java

名稱 描述
BIO 阻塞式IO,採用傳統的java IO進行操做,該模式下每一個請求都會建立一個線程,適用於併發量小的環境
NIO 同步非阻塞,tomcat8.0後的默認模式
APR tomcat以JNI形式調用http服務器的核心動態連接庫來處理文件讀取和網絡傳輸操做,須要編譯安裝APR庫
AIO 異步非阻塞,tomcat8.0後支持

配置方式

默認的配置文件:web

<Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
</Service>
複製代碼

只要將protocol替換爲如下幾種便可:apache

BIO: protocol =" org.apache.coyote.http11.Http11Protocol" (tomcat9不支持)編程

NIO: protocol ="org.apache.coyote.http11.Http11NioProtocol"tomcat

AIO: protocol ="org.apache.coyote.http11.Http11Nio2Protocol"服務器

APR: protocol ="org.apache.coyote.http11.Http11AprProtocol"網絡

概念介紹

同步、異步

同步:本身親自去買飯。(Java本身處理IO讀寫)架構

異步:點外賣,本身用走路去飯館的時間去幹別的事(Java將IO讀寫委託給操做系統處理,須要將數據緩衝區地址和大小傳給操做系統(送餐地址,數量)併發

阻塞、非阻塞

阻塞:食堂排隊,只能等待(使用阻塞IO是,Java調用會一直阻塞到讀寫完成才返回)。框架

非阻塞:取號,坐在位置上休息,等阿姨喊,同時能夠詢問是否輪到本身了(使用非阻塞IO時,若是不能讀寫,Java調用會立刻返回,當IO事件分發器會通知可讀寫時再繼續讀寫 ,不斷循環到讀寫完成)。

Java對BIO、NIO、AIO的支持

Java BIO : 同步並阻塞,服務器實現模式爲一個鏈接一個線程,即客戶端有鏈接請求時服務器端就須要啓動一個線程進行處理,若是這個鏈接不作任何事情會形成沒必要要的線程開銷,固然能夠經過線程池機制改善。

Java NIO : 同步非阻塞,服務器實現模式爲一個請求一個線程,即客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求時才啓動一個線程進行處理。

Java AIO(NIO.2) : 異步非阻塞,服務器實現模式爲一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啓動線程進行處理

使用場景

BIO方式適用於鏈接數目比較小且固定的架構,這種方式對服務器資源要求比較高,併發侷限於應用中,JDK1.4之前的惟一選擇,但程序直觀簡單易理解。

NIO方式適用於鏈接數目多且鏈接比較短(輕操做)的架構,好比聊天服務器,併發侷限於應用中,編程比較複雜,JDK1.4開始支持。

AIO方式使用於鏈接數目多且鏈接比較長(重操做)的架構,好比相冊服務器,充分調用OS參與併發操做,編程比較複雜,JDK7開始支持。

線程模型

BIO

啓動時,JIoEndpoint組件內部的Acceptor組件將啓動某個端口的監聽,一個請求到來後將被扔進線程池Executor,線程池進行任務處理處理,處理過程當中將經過Http11Processor組件對HTTP協議解析並傳遞到Engine容器繼續處理。

LimitLatch

Tomcat的流量控制是經過AQS(AbstractQueuedSynchronizer)併發框架實現的,經過AQS實現更有靈活性和定製型。

LimitLatch用來控制tomcat的流量,每接收一個套接字(Socket)那麼count+1,反之則減小 。若是超過最大限制,AQS將接收線程阻塞,中止接收套接字,直到某些套接字處理完關閉後從新喚起接收線程往下接收套接字。

Tomcat默認同時接收的客戶端鏈接數爲200,但能夠經過server.xml中的<Connector>節點的maxConnections進行調節,BIO模式下,最大鏈接數與最大線程數比例爲1:1。

同時,與最大鏈接數相關的還有 acceptCount參數,默認值爲100。能夠參考一下情形:

1)接受一個請求,此時tomcat起動的線程數沒有到達maxThreads,tomcat會起動一個線程來處理此請求。

2)接受一個請求,此時tomcat起動的線程數已經到達maxThreads,tomcat會把此請求放入等待隊列,等待空閒線程。

3)接受一個請求,此時tomcat起動的線程數已經到達maxThreads,等待隊列中的請求個數也達到了acceptCount,此時tomcat會直接拒絕這次請求,返回connection refused。

NIO

與BIO相比,NIO多了Poller組件,它能夠在非阻塞I/O方式下輪詢多個客戶端鏈接,不斷檢測,處理各類事件,例如不斷檢測各個鏈接是否可讀,對於可讀的客戶端鏈接嘗試進行讀取並解析消息報文。

Poller池的大小應爲: Math.min(2,Runtime.getRuntime().availableProcessors())

壓測併發測試

Jmeter工具下載與使用

1)下載

打開Jmeter官網,進行工具的下載,jmeter.apache.org/download_jm…

2)解壓

解壓到相應的目錄後,以管理員的身份打開bin目錄下的jmeter.bat。

啓動後等待一段時間會彈出圖形化界面:

3)使用

啓動一個java web程序,開放端口localhost:8080,使用Jmeter對其進行壓測,步驟以下:

1:新建線程組

2:設置線程組參數

3:新增http請求默認值

4:添加要壓測的http請求

下圖第一個紅框內的協議、IP、端口不須要設置,會使用步驟3中設置的默認值,只需設置請求路徑Path便可,這裏填入/task2_1_war_exploded/hello,這是個人接口路徑

5:新增監聽器,用於查看壓測結果。

6:運行

1)Label:每一個 JMeter 的 element(例如 HTTP Request)都有一個 Name 屬性,label顯示的就是 Name 屬性的值 。

2)#Samples:表示你此次測試中一共發出了多少個請求。

3)Average:平均響應時間——默認狀況下是單個 Request 的平均響應時間,當使用了 Transaction Controller 時,也能夠以Transaction 爲單位顯示平均響應時間。(單位ms)

4)Median:中位數,也就是 50% 用戶的響應時間。

5)90% Line:90% 用戶的響應時間。

6)Min:最小響應時間。

7)Max:最大響應時間。

8)Error%:本次測試中出現錯誤的請求的數量/請求的總數。

9)Throughput:吞吐量——默認狀況下表示每秒完成的請求數(Request per Second),當使用了 Transaction Controller 時,也能夠表示相似 LoadRunner 的 Transaction per Second 數。

10)KB/Sec:每秒從服務器端接收到的數據量,至關於LoadRunner中的Throughput/Sec 。

壓測結果

tomcat模式 併發數 樣本數 平均響應時間 吞吐量 錯誤率 接收Kb/s 發送Kb/s
nio 200 20000 147 1176.3/s 18.52% 817.18 134.78
nio 300 30000 236 1029.1/s 45.02% 1278.89 79.57
nio 500 50000 493 842.3/s 70.38% 1490.38 35.09
aio 200 20000 114 1357.1/s 18.70% 947.83 155.15
aio 300 30000 254 949.5/s 59.03% 1455.15 54.71
aio 500 50000 401 1020.9/s 64.70% 1687.59 50.68

能夠發現二者性能差很少。同時能夠發現,在當前配置下,併發數在200時(循環次數爲100)就有點撐不住了。

相關文章
相關標籤/搜索