摘要:本文將介紹的參數(shù)的重要性以及在發(fā)生時(shí)對(duì)系統(tǒng)整體性能的顯著影響。我們來(lái)看下的選項(xiàng)在發(fā)生時(shí)會(huì)對(duì)系統(tǒng)帶來(lái)哪些影響。所以這些請(qǐng)求將會(huì)放到堆積隊(duì)列,隊(duì)列的長(zhǎng)度是的中設(shè)置的。從而導(dǎo)致進(jìn)程的數(shù)量超過(guò),并觸發(fā)了操作系統(tǒng)進(jìn)行內(nèi)存交換的閥值。
原文鏈接:http://www.cubrid.org/blog/dev-platform/maxclients-in-apache-and-its-effect-on-tomcat-during-full-gc/
本文是GC專(zhuān)家系列中的第四篇。在第一篇理解Java垃圾回收中我們學(xué)習(xí)了幾種不同的GC算法的處理過(guò)程,GC的工作方式,新生代與老年代的區(qū)別。所以,你應(yīng)該已經(jīng)了解了JDK 7中的5種GC類(lèi)型,以及每種GC對(duì)性能的影響。
在第二篇Java垃圾回收的監(jiān)控中介紹了在真實(shí)場(chǎng)景中JVM是如何運(yùn)行GC,如何監(jiān)控GC數(shù)據(jù)以及有哪些工具可用來(lái)方便進(jìn)行GC監(jiān)控。
在第三篇GC 調(diào)優(yōu)中基于真實(shí)案例介紹了可用于GC調(diào)優(yōu)的最佳選項(xiàng)。同時(shí)也描述了如何通過(guò)降低移動(dòng)到老年代中對(duì)象的數(shù)量來(lái)縮短Full GC耗時(shí),以及如何設(shè)置GC類(lèi)型及內(nèi)存大小。
本文將介紹Apache的MaxClients參數(shù)的重要性以及在GC發(fā)生時(shí)對(duì)系統(tǒng)整體性能的顯著影響。通過(guò)幾個(gè)例子,你將會(huì)更清晰的理解MaxClients值所引發(fā)的問(wèn)題。最后會(huì)介紹如何依據(jù)系統(tǒng)的可用內(nèi)存來(lái)為MaxClients設(shè)置合理的數(shù)值。
MaxClients對(duì)系統(tǒng)的影響NHN的服務(wù)運(yùn)行環(huán)境中有大量的流控(Throttle valve)選項(xiàng),這些選項(xiàng)對(duì)系統(tǒng)的穩(wěn)定運(yùn)行具有重要作用。我們來(lái)看下Apache的MaxClients選項(xiàng)在Tomcat發(fā)生Full GC時(shí)會(huì)對(duì)系統(tǒng)帶來(lái)哪些影響。
大部分的開(kāi)發(fā)人員都知道GC 發(fā)生中會(huì)伴隨著"stop the world(STW)現(xiàn)象"(具體詳情參考理解Java垃圾回收)。尤其是NHN的Java開(kāi)發(fā)人員可能都經(jīng)歷過(guò)在Tomcat中由GC相關(guān)問(wèn)題而導(dǎo)致的系統(tǒng)崩潰。因?yàn)镴VM管理內(nèi)存,因此Java應(yīng)用系統(tǒng)不可避免的會(huì)遇到GC引起的STW現(xiàn)象。
在你開(kāi)發(fā)的線上系統(tǒng)中,GC每天都會(huì)發(fā)生很多次。在GC發(fā)生時(shí),即便TTS沒(méi)有發(fā)生,卻依然可能會(huì)給用戶(hù)503的錯(cuò)誤響應(yīng)。
系統(tǒng)運(yùn)行環(huán)境根據(jù)結(jié)構(gòu)特點(diǎn),Web服務(wù)更適合于做橫向擴(kuò)展而非單純的提高單一機(jī)器的性能。所以通常根據(jù)性能需要,Web服務(wù)的服務(wù)器部署結(jié)構(gòu)由一臺(tái)Apache服務(wù)器和多臺(tái)Tomcat服務(wù)器組成。在本文中,假設(shè)一個(gè)Apache服務(wù)和Tomcat服務(wù)部署在同一臺(tái)物理主機(jī)上,如下圖所示:
圖1: 本文假設(shè)的服務(wù)運(yùn)行環(huán)境
作為參考,本文所述參數(shù)均是基于Apache 2.2.21(prefork MPM),Tomcat 6.0.35,jdk 1.6.0_24,并運(yùn)行在CentOS 4.7.2(32位)操作系統(tǒng)上。
系統(tǒng)內(nèi)存2GB,并使用ParallelOldGC垃圾回收,默認(rèn)開(kāi)啟了AdaptiveSizePolicy選項(xiàng)并設(shè)置堆大小為600MB。
STW 和 HTTP 503假設(shè)Apache的流量為200QPS,并開(kāi)啟10個(gè)httpd處理進(jìn)程(盡管實(shí)際場(chǎng)景依賴(lài)于請(qǐng)求的響應(yīng)時(shí)間)。在這種前提下,假設(shè)full GC導(dǎo)致的停頓耗時(shí)1秒,如果Tomcat發(fā)生了Full GC將會(huì)怎么樣?
首先你能想到的是full GC導(dǎo)致Tomcat停頓,處理中的請(qǐng)求將得不到響應(yīng)。如果這樣,Tomcat暫停,請(qǐng)求得不到處理,Apache將會(huì)怎么樣?
即使Tomcat因Full GC而暫停處理,而請(qǐng)求卻仍以200 req/s的速度到達(dá)Apache。在full GC發(fā)生前,只需要10個(gè)或者稍微多一點(diǎn)的httpd進(jìn)程就可以快速響應(yīng)服務(wù)請(qǐng)求。但是現(xiàn)在Tomcat暫停了,為了處理新的請(qǐng)求Apache將持續(xù)創(chuàng)建新的httpd進(jìn)程直到httpd.conf文件中定義的MaxClients閥值。因?yàn)?b>MaxClients默認(rèn)值為256,所以200 req/s的請(qǐng)求并不會(huì)帶來(lái)太大問(wèn)題。
這個(gè)時(shí)候,新創(chuàng)建的httpd 進(jìn)程會(huì)怎么樣?
Httpd 進(jìn)程使用mod_jk模塊管理的AJP連接池中的空閑連接把請(qǐng)求發(fā)送到Tomcat。如果沒(méi)有空閑連接,則會(huì)要求創(chuàng)建新的連接。然而因?yàn)門(mén)omcat處理暫停狀態(tài),新建連接的請(qǐng)求將被拒絕。所以這些請(qǐng)求將會(huì)放到堆積隊(duì)列(backlog queue),隊(duì)列的長(zhǎng)度是server.xml的AJP Connector中設(shè)置的。
如果請(qǐng)求數(shù)據(jù)超出了堆積隊(duì)列的長(zhǎng)度,Apache將會(huì)收到連接拒絕錯(cuò)誤,并把這個(gè)錯(cuò)誤以HTTP 503的方式返回給用戶(hù)。
在本例的中,堆積隊(duì)列的長(zhǎng)度默認(rèn)設(shè)置為100,而請(qǐng)求速度為200 req/s,因此在由full GC導(dǎo)致Tomcat暫停的這1秒中,將有超過(guò)100的請(qǐng)求將會(huì)收到503錯(cuò)誤。
Full GC結(jié)束之后,堆積隊(duì)列中的socket連接會(huì)被Tomcat接收并分配給工作線程(最大工作線程數(shù)由MaxThreads決定,默認(rèn)值為200)來(lái)處理請(qǐng)求。
MaxClients和堆積隊(duì)列在上面的場(chǎng)景中,如何設(shè)置才能避免給用戶(hù)返回503錯(cuò)誤?
首先我們需要知道,應(yīng)該設(shè)置足夠的堆積隊(duì)列長(zhǎng)度以容納在Tomcat Full GC導(dǎo)致的暫停期間流入的請(qǐng)求。因此堆積隊(duì)列最小長(zhǎng)度至少為200(上文中QPS為200)。
這樣配置以后,是否還有其他問(wèn)題?
把堆積隊(duì)列長(zhǎng)度設(shè)置為200后,我們?cè)俅沃貜?fù)上面的場(chǎng)景。結(jié)果問(wèn)題卻比之前更加嚴(yán)重。
正常情況下系統(tǒng)內(nèi)存使用量維持在50%,而在發(fā)生Full GC時(shí)內(nèi)存使用卻迅速上升到100%,引起內(nèi)存交換區(qū)(swap)使用量的極劇增加。更為嚴(yán)重的是Full GC導(dǎo)致的響應(yīng)停頓由原來(lái)的1秒增加到了4秒,直接后果就是期間系統(tǒng)像掛掉了一樣,不能響應(yīng)任何請(qǐng)求。
在之前的場(chǎng)景中,只有100左右的請(qǐng)求會(huì)收到 503 的錯(cuò)誤,而增加堆積隊(duì)列到200后卻導(dǎo)致了500甚至更多的請(qǐng)求被掛起至少3秒不能收到任何響應(yīng)。
這個(gè)例子很好的證明了如果不能準(zhǔn)備的理清配置信息之間的因果關(guān)系,可能會(huì)對(duì)系統(tǒng)帶來(lái)極為嚴(yán)重的影響。
為什么會(huì)這樣?
原理就是要清楚MaxClients選項(xiàng)的特性。
MaxClients的值不易設(shè)置過(guò)大,設(shè)置MaxClients的關(guān)鍵在于即便創(chuàng)建了MaxClients數(shù)量的httpd進(jìn)程,也要需要維持應(yīng)用系統(tǒng)的內(nèi)存使用量不應(yīng)超過(guò)80%。
系統(tǒng)交換區(qū)默認(rèn)值為60,因此如果內(nèi)存使用超過(guò)80%,系統(tǒng)將會(huì)發(fā)生頻繁的內(nèi)存交換。
我們?cè)賮?lái)看下為什么這個(gè)特性會(huì)導(dǎo)致上面所述的嚴(yán)重后果。
當(dāng)請(qǐng)求的QPS為200時(shí),Tomcat會(huì)被Full GC暫停響應(yīng),然后把堆積列隊(duì)容量設(shè)置為200。起初大約有100個(gè)額外的httpd 進(jìn)程會(huì)被Apache創(chuàng)建,緊接著內(nèi)存使用量超過(guò)了80%,引起操作系統(tǒng)主動(dòng)的使用交換區(qū)的內(nèi)存空間,而因GC存活在JVM老年代中的對(duì)象被操作系統(tǒng)誤認(rèn)為長(zhǎng)時(shí)間未使用,從而導(dǎo)致這些對(duì)象被移動(dòng)到交換區(qū)。
最后,當(dāng)GC過(guò)程中涉及到交換區(qū)時(shí),耗時(shí)就會(huì)迅速增加。而后httpd進(jìn)程數(shù)繼續(xù)增加,導(dǎo)致內(nèi)存使用量達(dá)到了100%,從而出現(xiàn)了上述的嚴(yán)重后果。
上述案例的前后區(qū)別僅在于堆積隊(duì)列的長(zhǎng)度:100和200。但為什么在200時(shí)會(huì)出現(xiàn)更嚴(yán)重的狀況?
原因是堆積隊(duì)列不同的長(zhǎng)度導(dǎo)致了httpd進(jìn)程數(shù)的不同。當(dāng)值為100時(shí),在發(fā)生Full GC時(shí)100個(gè)請(qǐng)求所要求創(chuàng)建的連接被置于堆積隊(duì)列中。再有新的請(qǐng)求會(huì)被拒絕并返回503錯(cuò)誤,所以系統(tǒng)的整個(gè)httpd的進(jìn)程數(shù)僅超出100很少的數(shù)量。
但當(dāng)隊(duì)列長(zhǎng)度設(shè)置為200時(shí),有200個(gè)請(qǐng)求被接收并置于隊(duì)列中。從而導(dǎo)致httpd進(jìn)程的數(shù)量超過(guò)200,并觸發(fā)了操作系統(tǒng)進(jìn)行內(nèi)存交換的閥值。
所以,如果不顧內(nèi)存使用情況而一味的加大MaxClients的數(shù)值,將會(huì)導(dǎo)致Full GC時(shí)httpd進(jìn)程數(shù)迅速增加,引進(jìn)內(nèi)存交換并最終降低系統(tǒng)的整體性能。
所以如何設(shè)置MaxClients,如何找到當(dāng)前系統(tǒng)的閥值?
MaxClients 取值的計(jì)算方式如果系統(tǒng)總內(nèi)存為2GB,設(shè)置MaxClient的值需要保證在任何時(shí)候內(nèi)存的使用量不超過(guò)80%即1.6GB,從而避免因內(nèi)存交換導(dǎo)致的性能下降。也就是說(shuō)僅有1.6GB空間供Apache, Tomcat和其他默認(rèn)安裝的代理程序共享和分配內(nèi)存。
假如默認(rèn)安裝的代理程序占用200M內(nèi)存;Tomcat的堆空間設(shè)置-Xmx為600M,如下圖所示,Tomcat總占用量將725M (持久代 + 本地堆空間)。Apache可使用的空間為剩下的700M。
圖 2:Top命令的截圖
對(duì)于Apache的700M內(nèi)存,該如何設(shè)置合理的MaxClients值?
當(dāng)然這也取決于Apache加載的模塊類(lèi)型和數(shù)量。以NHN的Web服務(wù)為例,把Apache當(dāng)作簡(jiǎn)單的代理使用,根據(jù)上圖RES顯示,4M空間對(duì)于每個(gè)httpd進(jìn)程來(lái)說(shuō)已足夠使用。因此700M空間能設(shè)置的MaxClients為175。
總結(jié)可靠的服務(wù)配置要能夠在滿載的情況下降低系統(tǒng)停頓時(shí)間并能夠最大范圍的保證成功響應(yīng)用戶(hù)請(qǐng)求。對(duì)于Java應(yīng)用來(lái)說(shuō),必須要確認(rèn)在Full GC引起的SWT情況下,系統(tǒng)的配置是否能夠提供足夠可靠的服務(wù)。
如果為了應(yīng)對(duì)單純的請(qǐng)求增加和防止DDos攻擊,在不考慮內(nèi)存使用的情況下把MaxClients設(shè)置過(guò)大,那么MaxClients不但會(huì)失去作為流控的用途,反而會(huì)帶來(lái)更為嚴(yán)重的后果。
在這個(gè)案例中,解決問(wèn)題的最優(yōu)途徑是加大系統(tǒng)的內(nèi)存,或者設(shè)置MaxClients為175(上面的計(jì)算結(jié)果)以保證只有QPS超過(guò)175時(shí)才會(huì)出現(xiàn)503錯(cuò)誤。
作者:Dongsoon Choi,游戲服務(wù)技術(shù)支持團(tuán)隊(duì)高級(jí)工程師,NHN公司
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65373.html
摘要:調(diào)優(yōu)調(diào)優(yōu)中基于真實(shí)案例介紹了可用于調(diào)優(yōu)的最佳選項(xiàng)。的設(shè)置及其對(duì)的影響的設(shè)置及其對(duì)的影響中介紹了對(duì)選項(xiàng)在系統(tǒng)發(fā)生時(shí)對(duì)整體性能的影響。具體來(lái)說(shuō),我會(huì)介紹性能優(yōu)化的必要條件判斷是否需要優(yōu)化的步驟,同時(shí)也會(huì)列出在性能優(yōu)化過(guò)程中經(jīng)遇到的一些問(wèn)題。 1. 理解Java垃圾回收 理解Java垃圾回收中我們學(xué)習(xí)了幾種不同的GC算法的處理過(guò)程,GC的工作方式,新生代與老年代的區(qū)別。所以,你應(yīng)該已經(jīng)了解...
摘要:在本文中我將會(huì)介紹應(yīng)用性能優(yōu)化的一般原則。性能優(yōu)化的流程圖摘取自和合著的性能,描述了應(yīng)用性能優(yōu)化的處理流程。例如,對(duì)每臺(tái)服務(wù)器,你面臨著為單個(gè)分配堆內(nèi)存和運(yùn)行個(gè)并為每個(gè)分配堆內(nèi)存的選擇。不過(guò)位能使用堆內(nèi)存最大理論值只有。 原文鏈接:http://www.cubrid.org/blog/dev-platform/the-principles-of-java-application-per...
摘要:原文鏈接本篇是專(zhuān)家系列的第三篇。但是,請(qǐng)記住調(diào)優(yōu)是不得已時(shí)的選擇??s短耗時(shí)的單次執(zhí)行與相比,耗時(shí)有較明顯的增加。創(chuàng)建文件過(guò)程中,進(jìn)程會(huì)中斷,因此不要在正常運(yùn)行時(shí)系統(tǒng)上做此操作。因此校驗(yàn)結(jié)果并根據(jù)具體的服務(wù)需要,決定是否要進(jìn)行調(diào)優(yōu)。 原文鏈接:http://www.cubrid.org/blog/dev-platform/how-to-tune-java-garbage-collecti...
摘要:原文鏈接這是專(zhuān)家系列文章的第二篇。運(yùn)行在本地虛擬機(jī)上的應(yīng)用的又稱(chēng)為,通常與相同。性能數(shù)據(jù)需要持續(xù)觀察,因此在運(yùn)行時(shí)需要定時(shí)輸出的監(jiān)控信息。新生代容量的統(tǒng)計(jì)信息。是提供的一個(gè)式的圖表監(jiān)控工具。 原文鏈接:http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/ 這是GC專(zhuān)家系列文章的第二...
摘要:本文是成為專(zhuān)家系列的第一篇。然而,在多線程環(huán)境下,將會(huì)有別樣的狀況。在中正是通過(guò)解決了多線程問(wèn)題。在最后的并發(fā)清理階段,垃圾回收過(guò)程被真正執(zhí)行。在垃圾回收?qǐng)?zhí)行過(guò)程中,其他線程依然在執(zhí)行。 原文鏈接:http://www.cubrid.org/blog/de... 了解Java的垃圾回收(GC)原理能給我們帶來(lái)什么好處?對(duì)于軟件工程師來(lái)說(shuō),滿足技術(shù)好奇心可算是一個(gè),但重要的是理解GC能幫...
閱讀 1019·2021-09-30 09:58
閱讀 2852·2021-09-09 11:55
閱讀 2016·2021-09-01 11:41
閱讀 1005·2019-08-30 15:55
閱讀 3366·2019-08-30 12:50
閱讀 3511·2019-08-29 18:37
閱讀 3313·2019-08-29 16:37
閱讀 2024·2019-08-29 13:00