《java—Tomcat高性能調優方案詳解》要點:
本文介紹了java—Tomcat高性能調優方案詳解,希望對您有用。如果有疑問,可以聯系我們。
一丶原理
概要
Tomcat大致分為兩個部分,Connector組件及Container組件.Connector組件負責控制入口連接,并關聯著一個Executor.Container負責Servlet容器的實現,Executor負責具體的業務邏輯,如Servlet的執行.一個哀求到達服務器后,經過以下關鍵幾步,參見圖1:
圖一
OS與客戶端握手并建立連接,并將建立的連接放入完成隊列,不妨叫Acceptor Queque.這個隊列的長度便是Connector的acceptCount值.
Tomcat中的acceptor線程,賡續從Acceptor Queque中獲取連接.
Acceptor Queque隊列中沒有連接,Acceptor線程繼續監視
Acceptor Queque隊列中有新連接,Acceptor線程將檢查當前的連接數是否跨越了maxConnections
如果超過maxConnections,則阻塞.直到連接數小于maxConnections,acceptor線程將哀求交由Executor負責執行.
Executor將分配worker線程來處理哀求數據的讀取,處理(servlet的執行)以及響應.
參數
acceptCount
acceptCount 實際上是Bind Socket時候傳遞的backlog值,在linux平臺下含義是已經建立連接還沒有被應用獲取的連接隊列最大長度.此時,如果哀求個數達到了acceptCount,新進的哀求將拋出refuse connection.
maxConnections:
顧名思義,即Tomcat允許的同時存在的最大連接數.默認BIO模式下,這個數值等于maxThreads,即最大線程數.超過這個值后,acceptor線程被Block.新進入的連接將由acceptCount控制.當當前連接數小于這個數值時,acceptor線程被喚醒,新的連接能力進入Executor執行.
executor
JDK缺省的ThreadPoolExecutor的邏輯是:
如果線程數小于coreThreadSize, 優先建立新線程.
如果線程數大于coreThreadSize小于maxThreadSize,將哀求入隊列等待.
隊列滿的時候,才擴充線程數直到maxThreadSize.
當隊列滿,同時線程數大于maxThreadSize時,拋出異常.
Tomcat對JDK的ThreadPoolExecutor默認行為做了修改.使用承繼自無界隊列的LinkedBlockingQueue的TaskQueue,并改寫了其入隊策略,是的tomcat的Executor具有以下特性.
只要線程不足,而且小于maxThreads, 優先建立新線程.而不是超過coreSize,先入隊列.
Executor如果發生reject,則將任務繼續參加隊列.而默認隊列的size是Integer.MAX_VALUE,因此不會Reject.
在配置中,Executor可以單獨配置,并被整個Tomcat共享.如果不配置,則Connector組件將使用本身默認的實現.
maxThreads
Worker線程的最大值.每當一個哀求進來時,如果當前線程數小于這個值,則創建新的線程.如果大于這個值,則查找空閑線程.如果沒有空閑線程,則被Block住.
protocol
可以有三個取值,BIO,NIO, APR.BIO使用阻塞Socket實現,一個連接一個線程的模型.NIO使用的時候非阻塞socket實現.APR是apache實現的一個夸平臺的庫,也是apache http服務以來的核心網絡組件.
以上介紹的幾個參數之間存在著微妙的關系.一方面可以限制過多的哀求來保護系統資源,另一方面提供緩沖隊列來提高系統的吞吐量.在低并發條件下,默認值基本滿足要求.而在高并發的情況下,就需要根據具體的計算資源,評估以上參數的設置,來充分調動計算資源.
二丶應用
默認值的效果
背景中的case除了使用異步Servlet,后端依賴的服務也全部采用異步調用.即在tomcat的woker線程中,沒有任何阻塞,只是做純粹的本地CPU計算, 為了模擬服務失敗的情況,后端服務被mock住,并隨機sleep 0~3s.初次使用了tomcat的默認設置(具體值參見后表中第1條).由于后端woker線程很快(發送異步哀求后就結束了),一個線程在1s內可以處理多于一個的哀求.此時,如果maxConnections等于maxThreads 的值,很顯然不能完全激活全部工作線程.如圖2:
圖二
300個線程,只能達到140左右的吞吐量,tomcat worker線程只有17個上下,平均響應時間已經2s多了(理論上正常平均應該1.5s),繼續增加線程,返回異常,說明已經達到了極限值.可以理解為,在異步情況下,20個worker線程每秒就能處理140個哀求.
maxConnection的應用
為了將worker線程打滿,同時對后端的異步服務有足夠的信心,逐步將maxConnection調整到2000,使用2000個并發打壓.此時200個worker線程都工作了.吞吐量已經達到了1308(如圖3),此時應該是應用最大吞吐量了.至此,初步達到了預期效果.
圖三
NIO Connector的應用
還有個NIO Connector,看到名字便是支持異步的IO了,在其它參數不變的情況下,換成NIO Connector.如圖4所示,在吞吐量基本不變的情況下,線程數基本減少了一半.
圖四
在啟用NIO Connector,servlet及后端調用不異步的話,如圖所示5,顯然吞吐量上不去,并且還有所下降.
圖五
圖六
為了充分發揮tomcat的潛能,需要綜合評估這幾個重要參數.當worker線程處理足夠快的時候,可以適當提高maxConnections值,以便更多的哀求得到處理.
反之,如果后端線程處理較慢,則可考慮減少maxConnections及QueueSize,避免哀求堆積而造成哀求超時.另外NIO能更高效處理網絡連接及哀求.在全棧異步的情況下,能有效減少Worker線程數.
好了到這里, java—Tomcat高性能調優方案詳解就結束了,,不足之處還望大家多多原諒!!覺得收獲的話可以點個關注收藏轉發一波喔,謝謝大佬們支持.(吹一波,233~~)
下面和大家交流幾點編程的經驗:
1、多寫多敲代碼,好的代碼與扎實的基礎知識必定是實踐出來的
2丶 測試、測試再測試,如果你不徹底測試本身的代碼,那恐怕你開發的就不只是代碼,可能還會聲名狼藉.
3丶 簡化算法,代碼如惡魔,在你完成編碼后,應回頭而且優化它.從長遠來看,這里或那里一些的改進,會讓后來的支持人員更加輕松.
4、可以去騰訊課堂的圖靈學院學習一下java架構實戰案例,還挺不錯的.
最后,每一位讀到這里的網友,感謝你們能耐心地看完.希望在成為一名更優秀的Java法式員的道路上,我們可以一起學習、一起進步.
維易PHP培訓學院每天發布《java—Tomcat高性能調優方案詳解》等實戰技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養人才。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/7848.html