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 : 同步並阻塞,服務器實現模式爲一個鏈接一個線程,即客戶端有鏈接請求時服務器端就須要啓動一個線程進行處理,若是這個鏈接不作任何事情會形成沒必要要的線程開銷,固然能夠經過線程池機制改善。
Java NIO : 同步非阻塞,服務器實現模式爲一個請求一個線程,即客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求時才啓動一個線程進行處理。
Java AIO(NIO.2) : 異步非阻塞,服務器實現模式爲一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啓動線程進行處理
BIO方式適用於鏈接數目比較小且固定的架構,這種方式對服務器資源要求比較高,併發侷限於應用中,JDK1.4之前的惟一選擇,但程序直觀簡單易理解。
NIO方式適用於鏈接數目多且鏈接比較短(輕操做)的架構,好比聊天服務器,併發侷限於應用中,編程比較複雜,JDK1.4開始支持。
AIO方式使用於鏈接數目多且鏈接比較長(重操做)的架構,好比相冊服務器,充分調用OS參與併發操做,編程比較複雜,JDK7開始支持。
啓動時,JIoEndpoint組件內部的Acceptor組件將啓動某個端口的監聽,一個請求到來後將被扔進線程池Executor,線程池進行任務處理處理,處理過程當中將經過Http11Processor組件對HTTP協議解析並傳遞到Engine容器繼續處理。
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。
Math.min(2,Runtime.getRuntime().availableProcessors())
打開Jmeter官網,進行工具的下載,jmeter.apache.org/download_jm…
解壓到相應的目錄後,以管理員的身份打開bin目錄下的jmeter.bat。
啓動後等待一段時間會彈出圖形化界面:
啓動一個java web程序,開放端口localhost:8080,使用Jmeter對其進行壓測,步驟以下:
下圖第一個紅框內的協議、IP、端口不須要設置,會使用步驟3中設置的默認值,只需設置請求路徑Path
便可,這裏填入/task2_1_war_exploded/hello
,這是個人接口路徑
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)就有點撐不住了。