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