tomcat調(diào)優(yōu)

image.png

線程池大小 = 每秒請求數(shù) × 平均請求處理時間

假設(shè)服務(wù)器是單核的:

線程池大小 = (線程 I/O 阻塞時間 + 線程 CPU 時間 )/ 線程 CPU 時間
其中:線程 I/O 阻塞時間 + 線程 CPU 時間 = 平均請求處理時間

對比一下兩個公式,你會發(fā)現(xiàn),平均請求處理時間在兩個公式里都出現(xiàn)了婚被,這說明請求時間越長堤器,需要更多的線程是毫無疑問的。
不同的是第一個公式是用每秒請求數(shù)來乘以請求處理時間孟抗;而第二個公式用請求處理時間來除以線程 CPU 時間,請注意 CPU 時間是小于請求處理時間的
雖然這兩個公式是從不同的角度來看待問題的,但都是理想情況革骨,都有一定的前提條件。

  1. 請求處理時間越長析恋,需要的線程數(shù)越多良哲,但前提是 CPU 核數(shù)要足夠,如果一個 CPU 來支撐 10000 TPS 并發(fā)助隧,創(chuàng)建 10000 個線程筑凫,顯然不合理,會造成大量線程上下文切換并村。
  2. 請求處理過程中巍实,I/O 等待時間越長,需要的線程數(shù)越多哩牍,前提是 CUP 時間和 I/O 時間的比率要計(jì)算的足夠準(zhǔn)確棚潦。
  3. 請求進(jìn)來的速率越快,需要的線程數(shù)越多膝昆,前提是 CPU 核數(shù)也要跟上瓦盛。

實(shí)際場景下如何確定線程數(shù)

  • 那么在實(shí)際情況下洗显,線程池的個數(shù)如何確定呢?這是一個迭代的過程原环,先用上面兩個公式大概算出理想的線程數(shù)挠唆,再反復(fù)壓測調(diào)整,從而達(dá)到最優(yōu)
  • 一般來說嘱吗,如果系統(tǒng)的 TPS 要求足夠大玄组,用第一個公式算出來的線程數(shù)往往會比公式二算出來的要大。我建議選取這兩個值中間更靠近公式二的值谒麦。也就是先設(shè)置一個較小的線程數(shù)俄讹,然后進(jìn)行壓測,當(dāng)達(dá)到系統(tǒng)極限時(錯誤數(shù)增加绕德,或者響應(yīng)時間大幅增加)患膛,再逐步加大線程數(shù),當(dāng)增加到某個值耻蛇,再增加線程數(shù)也無濟(jì)于事踪蹬,甚至 TPS 反而下降,那這個值可以認(rèn)為是最佳線程數(shù)臣咖。
  • 線程池中其他的參數(shù)跃捣,最好就用默認(rèn)值,能不改就不改夺蛇,除非在壓測的過程發(fā)現(xiàn)了瓶頸疚漆。如果發(fā)現(xiàn)了問題就需要調(diào)整,比如 maxQueueSize刁赦,如果大量任務(wù)來不及處理都堆積在 maxQueueSize 中娶聘,會導(dǎo)致內(nèi)存耗盡,這個時候就需要給 maxQueueSize 設(shè)一個限制甚脉。當(dāng)然丸升,這是一個比較極端的情況了。
    再比如 minSpareThreads 參數(shù)宦焦,默認(rèn)是 25 個線程发钝,如果你發(fā)現(xiàn)系統(tǒng)在閑的時候用不到 25 個線程,就可以調(diào)小一點(diǎn)波闹;如果系統(tǒng)在大部分時間都比較忙酝豪,線程池中的線程總是遠(yuǎn)遠(yuǎn)多于 25 個,這個時候你就可以把這個參數(shù)調(diào)大一點(diǎn)精堕,因?yàn)檫@樣線程池就不需要反復(fù)地創(chuàng)建和銷毀線程了孵淘。

總結(jié)

  • 今天學(xué)習(xí)了 I/O 調(diào)優(yōu),也就是如何選擇連接器的類型歹篓,以及在選擇過程中有哪些需要注意的地方瘫证。
  • 后面還聊到 Tomcat 線程池的各種參數(shù)揉阎,其中最重要的參數(shù)是最大線程數(shù) maxThreads。理論上我們可以通過利特爾法則或者 CPU 時間與 I/O 時間的比率背捌,計(jì)算出一個理想值毙籽,這個值只具有指導(dǎo)意義,因?yàn)樗艿礁鞣N資源的限制毡庆,實(shí)際場景中坑赡,我們需要在理想值的基礎(chǔ)上進(jìn)行壓測,來獲得最佳線程數(shù)么抗。

<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
connectionTimeout="30000"
URIEncoding="UTF-8"
minSpareThreads="100"
maxThreads="4096"
acceptCount="10000"
enableLookups="false"
disableUploadTimeout="true"
redirectPort="8443" />

  • org.apache.coyote.http11.Http11Nio2Protocol
    在tomcat8中有最新的nio2毅否,速度更快,也建議使用nio2蝇刀,nio2連接器需要tomcat8.0以上才有
  • connectionTimeout
    網(wǎng)絡(luò)超時時間螟加,單位:毫秒,設(shè)置為 0 表示永不超時吞琐,這樣設(shè)置有隱患的捆探。通常可設(shè)置為 30000 毫秒顽分,可根據(jù)檢測實(shí)際情況徐许,適當(dāng)修改
  • URIEncoding:tomcat容器編碼配置
  • maxThreads : tomcat處理請求是是用的線程來處理的施蜜,這個表示tomcat的最大線程數(shù)卒蘸,默認(rèn)200(maxThreads='5000' 最大可以處理5000發(fā)并發(fā)請求 nginx一般可以達(dá)到5w)
  • minSpareThreads:最小空閑線程數(shù),表示沒人訪問的時候翻默,也開多少線程等待訪問(最小要啟動的線程數(shù)去處理用戶的請求缸沃,這個隨著用戶的請求是不斷增加的)
  • acceptCount:指定當(dāng)所有可以使用的處理請求的線程數(shù)都被使用時,可傳入連接請求的最大隊(duì)列長度修械,超過這個數(shù)的請求將不予處理趾牧,默認(rèn)為100個。
  • enableLookups:反查域名肯污,true返回遠(yuǎn)程主機(jī)的主機(jī)名翘单,false返回ip地址,為了提高處理能力蹦渣,應(yīng)設(shè)置為 false(Tomcat接收用戶請求根據(jù)用戶的IP去反查用戶的主機(jī)名哄芜,相當(dāng)于查找DNS,這樣做沒有意義的 主要是為了安全柬唯,看看用戶ip可不可以解析出域名认臊,這個消耗時間 ,這個要關(guān)閉)
  • disableUploadTimeout="true" 禁止上傳超時锄奢,上傳時是否使用超時機(jī)制

tomcat中maxConnections失晴、maxThreads剧腻、acceptCount的具體含義

比較容易弄混的是maxThreads和maxConnections這兩個參數(shù):maxThreads是指Tomcat線程池做多能起的線程數(shù),而maxConnections則是Tomcat一瞬間做多能夠處理的并發(fā)連接數(shù)涂屁。比如maxThreads=1000书在,maxConnections=800,假設(shè)某一瞬間的并發(fā)時1000拆又,那么最終Tomcat的線程數(shù)將會是800蕊温,即同時處理800個請求,剩余200進(jìn)入隊(duì)列“排隊(duì)”遏乔,如果acceptCount=100义矛,那么有100個請求會被拒掉。
根據(jù)前面所說盟萨,只是并發(fā)那一瞬間Tomcat會起800個線程處理請求凉翻,但是穩(wěn)定后,某一瞬間可能只有很少的線程處于RUNNABLE狀態(tài)捻激,大部分線程是TIMED_WAITING制轰,如果你的應(yīng)用處理時間夠快的話。所以真正決定Tomcat最大可能達(dá)到的線程數(shù)是maxConnections這個參數(shù)和并發(fā)數(shù)胞谭,當(dāng)并發(fā)數(shù)超過這個參數(shù)則請求會排隊(duì)垃杖,這時響應(yīng)的快慢就看你的程序性能了

一、accept-count:最大等待數(shù)

官方文檔的說明為:當(dāng)所有的請求處理線程都在使用時丈屹,所能接收的連接請求的隊(duì)列的最大長度调俘。當(dāng)隊(duì)列已滿時,任何的連接請求都將被拒絕旺垒。accept-count的默認(rèn)值為100彩库。
詳細(xì)的來說:當(dāng)調(diào)用HTTP請求數(shù)達(dá)到tomcat的最大線程數(shù)時,還有新的HTTP請求到來先蒋,這時tomcat會將該請求放在等待隊(duì)列中骇钦,這個acceptCount就是指能夠接受的最大等待數(shù),默認(rèn)100竞漾。如果等待隊(duì)列也被放滿了眯搭,這個時候再來新的請求就會被tomcat拒絕(connection refused)。

二业岁、maxThreads:最大線程數(shù)(線程池中最大允許容納的線程數(shù)量)

每一次HTTP請求到達(dá)Web服務(wù)鳞仙,tomcat都會創(chuàng)建一個線程來處理該請求,那么最大線程數(shù)決定了Web服務(wù)容器可以同時處理多少個請求叨襟。maxThreads默認(rèn)200繁扎,肯定建議增加。但是,增加線程是有成本的梳玫,更多的線程爹梁,不僅僅會帶來更多的線程上下文切換成本,而且意味著帶來更多的內(nèi)存消耗提澎。JVM中默認(rèn)情況下在創(chuàng)建新線程時會分配大小為1M的線程棧姚垃,所以,更多的線程異味著需要更多的內(nèi)存盼忌。線程數(shù)的經(jīng)驗(yàn)值為:1核2g內(nèi)存為200积糯,線程數(shù)經(jīng)驗(yàn)值200;4核8g內(nèi)存谦纱,線程數(shù)經(jīng)驗(yàn)值800看成。

三、maxConnections:最大連接數(shù)(BIO默認(rèn)為maxThreads的值跨嘉,NIO默認(rèn)為10000)

官方文檔的說明為:
這個參數(shù)是指在同一時間川慌,tomcat能夠接受的最大連接數(shù)。對于Java的阻塞式BIO祠乃,默認(rèn)值是maxthreads的值梦重;如果在BIO模式使用定制的Executor執(zhí)行器,默認(rèn)值將是執(zhí)行器中maxthreads的值亮瓷。對于Java 新的NIO模式琴拧,maxConnections 默認(rèn)值是10000。
對于windows上APR/native IO模式嘱支,maxConnections默認(rèn)值為8192蚓胸,這是出于性能原因,如果配置的值不是1024的倍數(shù)斗塘,maxConnections 的實(shí)際值將減少到1024的最大倍數(shù)赢织。
如果設(shè)置為-1亮靴,則禁用maxconnections功能馍盟,表示不限制tomcat容器的連接數(shù)。
maxConnections和accept-count的關(guān)系為:當(dāng)連接數(shù)達(dá)到最大值maxConnections后茧吊,系統(tǒng)會繼續(xù)接收連接贞岭,但不會超過acceptCount的值。

圖解:maxConnections搓侄、maxThreads瞄桨、acceptCount關(guān)系

用一個形象的比喻,通俗易懂的解釋一下tomcat的最大線程數(shù)(maxThreads)讶踪、最大等待數(shù)(acceptCount)和最大連接數(shù)(maxConnections)三者之間的關(guān)系芯侥。

我們可以把tomcat比做一個火鍋店,流程是取號、入座柱查、叫服務(wù)員廓俭,可以做一下三個形象的類比:
(1)acceptCount 最大等待數(shù)
可以類比為火鍋店的排號處能夠容納排號的最大數(shù)量;排號的數(shù)量不是無限制的唉工,火鍋店的排號到了一定數(shù)據(jù)量之后研乒,服務(wù)往往會說:已經(jīng)客滿。
(2)maxConnections 最大連接數(shù)
可以類比為火鍋店的大堂的餐桌數(shù)量淋硝,也就是可以就餐的桌數(shù)雹熬。如果所有的桌子都已經(jīng)坐滿,則表示餐廳已滿谣膳,已經(jīng)達(dá)到了服務(wù)的數(shù)量上線竿报,不能再有顧客進(jìn)入餐廳了。
(3)maxThreads:最大線程數(shù)
可以類比為廚師的個數(shù)继谚。每一個廚師仰楚,在同一時刻,只能給一張餐桌炒菜犬庇,就像極了JVM中的一條線程僧界。

整個就餐的流程,大致如下:

(1)取號:如果maxConnections連接數(shù)沒有滿臭挽,就不需要取號捂襟,因?yàn)檫€有空余的餐桌,直接被大堂服務(wù)員領(lǐng)上餐桌欢峰,點(diǎn)菜就餐即可葬荷。如果 maxConnections 連接數(shù)滿了,但是取號人數(shù)沒有達(dá)到 acceptCount纽帖,則取號成功宠漩。如果取號人數(shù)已達(dá)到acceptCount,則拿號失敗懊直,會得到Tomcat的Connection refused connect 的回復(fù)信息扒吁。
(2)上桌:如果有餐桌空出來了,表示maxConnections連接數(shù)沒有滿室囊,排隊(duì)的人雕崩,可以進(jìn)入大堂上桌就餐。
(3)就餐:就餐需要廚師炒菜融撞。廚師的數(shù)量盼铁,比顧客的數(shù)量,肯定會少一些尝偎。一個廚師一定需要給多張餐桌炒菜饶火,如果就餐的人越多鹏控,廚師也會忙不過來。這時候就可以增加廚師肤寝,一增加到上限maxThreads的值牧挣,如果還是不夠,只能是拖慢每一張餐桌的上菜速度醒陆,這種情況瀑构,就是大家常見的“上一道菜吃光了,下一道菜還沒有上”尷尬場景刨摩。

maxConnections寺晌、maxThreads、acceptCount關(guān)系圖如下

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末澡刹,一起剝皮案震驚了整個濱河市呻征,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罢浇,老刑警劉巖陆赋,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嚷闭,居然都是意外死亡攒岛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進(jìn)店門胞锰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灾锯,“玉大人,你說我怎么就攤上這事嗅榕∷骋” “怎么了?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵凌那,是天一觀的道長兼雄。 經(jīng)常有香客問我,道長帽蝶,這世上最難降的妖魔是什么赦肋? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮嘲碱,結(jié)果婚禮上金砍,老公的妹妹穿的比我還像新娘。我一直安慰自己麦锯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布琅绅。 她就那樣靜靜地躺著扶欣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上料祠,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天骆捧,我揣著相機(jī)與錄音,去河邊找鬼髓绽。 笑死敛苇,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顺呕。 我是一名探鬼主播枫攀,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼株茶!你這毒婦竟也來了来涨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤启盛,失蹤者是張志新(化名)和其女友劉穎蹦掐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體僵闯,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卧抗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳖粟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颗味。...
    茶點(diǎn)故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖牺弹,靈堂內(nèi)的尸體忽然破棺而出浦马,到底是詐尸還是另有隱情,我是刑警寧澤张漂,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布晶默,位于F島的核電站,受9級特大地震影響航攒,放射性物質(zhì)發(fā)生泄漏磺陡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一漠畜、第九天 我趴在偏房一處隱蔽的房頂上張望币他。 院中可真熱鬧,春花似錦憔狞、人聲如沸蝴悉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拍冠。三九已至尿这,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間庆杜,已是汗流浹背射众。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晃财,地道東北人叨橱。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像断盛,于是被迫代替她去往敵國和親罗洗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容