可以通過(guò)修改許多服務(wù)器設置讓它更好地處理工作負載。根據服務(wù)器負載性質(zhì)的不同,文件服務(wù)器的調優(yōu)不同于數據庫服務(wù)器,兩個(gè)應用服務(wù)器也可能采用不同的方式調優(yōu)。調優(yōu)涉及把有限的服務(wù)器資源分配給操作系統和應用程序的不同部分,從而讓?xiě)贸绦虮M快做出響應。下面是調優(yōu)要考慮的領(lǐng)域:
這些方面經(jīng)常會(huì )相互影響。例如,可以為緩存分配內存,這可以減少磁盤(pán)訪(fǎng)問(wèn)或通過(guò)網(wǎng)絡(luò )的資源訪(fǎng)問(wèn)。本文的重點(diǎn)之一是與 Java 虛擬機 (JVM) 相關(guān)的內存調優(yōu)。JVM 有自己的內存管理系統,必須監視和配置這個(gè)系統。
服務(wù)器的 CPU 會(huì )在等待某些事件方面花費很多時(shí)間。最常見(jiàn)的情況是等待磁盤(pán)返回數據。多任務(wù)機制允許 CPU 在等待時(shí)做其他事情。因此,如果主機在 CPU 方面花費大量時(shí)間,那么購買(mǎi)更快的 CPU 會(huì )提高性能。
vmstat 命令提供關(guān)于系統時(shí)間消耗的實(shí)時(shí)細分信息,sar 工具套件適合進(jìn)行長(cháng)期監視。如果這些工具顯示 CPU 把大多數時(shí)間花費在用戶(hù)空間,空閑周期非常少,就應該考慮采取措施。在這種情況下,要么把負載轉移到其他服務(wù)器,要么提高 CPU 能力。
轉移負載可能意味著(zhù)在另一臺服務(wù)器上運行批作業(yè),或者把應用程序負載分配給多臺服務(wù)器。后一種方法是最理想的,這稱(chēng)為水平擴展。如果必須提高 CPU 能力,那么可以進(jìn)行物理升級,比如添加更多的 CPU;如果處于虛擬化環(huán)境,還可以重新分配更多資源。
一些負載本身不適合并行處理,所以跨多個(gè)服務(wù)器分配負載或添加更多 CPU 不會(huì )有幫助。在這種情況下,要使用更快的 CPU 并花時(shí)間優(yōu)化底層代碼,減少運行它所需的 CPU 周期。
內存調優(yōu)涉及許多方面。最簡(jiǎn)單的調優(yōu)措施是確保 RAM 足以容納應用程序,而不需要使用交換空間。操作系統的虛擬內存子系統允許應用程序分配的內存超過(guò)系統上實(shí)際存在的內存量,不足的部分由磁盤(pán)上的臨時(shí)存儲組成。與直接訪(fǎng)問(wèn) RAM 中的內存塊相比,把內存塊交換到磁盤(pán)并交換回來(lái)要慢得多,所以一般情況下應該避免這種做法。
虛擬內存子系統需要調優(yōu),因為在系統用完內存之前和發(fā)生某些事件時(shí),可能會(huì )把內存塊寫(xiě)到磁盤(pán),這時(shí)不得不使用交換空間。要檢查的主要是什么時(shí)候使用虛擬內存。隨著(zhù) UNIX® 系統上的空閑內存被逐漸分配掉,內核最終會(huì )發(fā)現它必須要尋找可以交換出去的內存頁(yè)面。在此之后,如果內核預計必須為請求內存的進(jìn)程分配內存,它就會(huì )開(kāi)始把一些頁(yè)面交換到磁盤(pán)。如果您知道內存足以處理工作負載,最好推遲這兩種交換活動(dòng)。
在 Solaris™ 上,通過(guò) /etc/system 中的可調項來(lái)調整內存。在 IBM® AIX® 操作系統上,使用 vmo 命令。在 Linux® 中,使用 /etc/sysctl.conf。它們的作用會(huì )隨著(zhù)操作系統的發(fā)展而變化,所以在做任何修改之前要仔細研究。
最后,安裝更多內存讓文件系統可以把文件和元數據緩存在內存中。大多數 UNIX 系統會(huì )嘗試用空閑內存執行緩存,這就是系統常??雌饋?lái)沒(méi)有空閑內存的原因。緩存可以減少磁盤(pán)活動(dòng),這對于 Web 服務(wù)器等工作負載非常重要。
磁盤(pán)比內存慢得多,所以過(guò)多的磁盤(pán)活動(dòng)是許多應用程序性能低下的原因。磁盤(pán)活動(dòng)可能源于交換,也可能源于應用程序或操作系統的請求。過(guò)多的日志記錄活動(dòng)也會(huì )爭用磁盤(pán)。
發(fā)現磁盤(pán)瓶頸的最佳工具是 iostat。這個(gè)工具可以指出在特定時(shí)間點(diǎn)發(fā)生了多少讀寫(xiě)操作,以及磁盤(pán)控制器的飽和程度有多大。如果有多個(gè)磁盤(pán),那么把負載分配到不同的磁盤(pán)上是加快讀寫(xiě)速度的有效方法,因為磁盤(pán)延遲的最大組成部分是尋道時(shí)間。不斷增長(cháng)的文件(比如日志文件和數據庫日志)應該放在單獨的磁盤(pán)上,與應用程序的磁盤(pán)和數據庫分開(kāi)。
vmstat 和 iostat 報告系統在等待 IO 方面花費的時(shí)間百分比,也就是 CPU 空閑而系統正在等待 IO 返回的時(shí)間。iowait 值高就意味著(zhù)磁盤(pán)緩慢或負載過(guò)大。
與磁盤(pán)密切相關(guān)的是可以打開(kāi)的文件描述符數量。如果用光了文件描述符,那么打開(kāi)文件的操作就會(huì )失敗。通常,ulimit 命令可以增加可用的文件描述符數量,但是操作系統對于 ulimit 可能有內核限制。
網(wǎng)絡(luò )對于大多數應用程序都很重要,因為網(wǎng)絡(luò )在服務(wù)器和客戶(hù)機之間來(lái)回傳輸數據。網(wǎng)絡(luò )慢常常導致應用程序看起來(lái)響應緩慢。應該做的第一件事是,確保所有服務(wù)器使用全雙工和最高的網(wǎng)絡(luò )速度,并相應地匹配交換機端口。交換機和服務(wù)器之間的速度和雙工不匹配是網(wǎng)絡(luò )問(wèn)題的常見(jiàn)原因。
操作系統會(huì )為網(wǎng)絡(luò )資源分配各種緩沖區。例如,操作系統為每個(gè) TCP 連接維護 TCP 發(fā)送隊列。這個(gè)隊列保存應用程序已經(jīng)發(fā)送,但是還沒(méi)有得到遠程端確認的數據(根據未確認數據包的數量,一些數據可能還未發(fā)送到網(wǎng)絡(luò ))。如果這個(gè)隊列滿(mǎn)了,就不允許應用程序發(fā)送更多數據,直到清理完積壓的隊列為止。
可以用 netstat -s 尋找緩存區擁擠的跡象,這個(gè)命令輸出網(wǎng)絡(luò )計數器的列表。其中包含 “queue” 或 “overflow” 的內容都與 TCP 隊列相關(guān),應該監視它們。這些計數器一般只在系統引導時(shí)重置,所以應該更關(guān)注隨時(shí)間增長(cháng)的數字。
如果 netstat -an 表明大量連接處于等待狀態(tài)(比如 CLOSE_WAIT 或 FIN_WAIT_1),那么由于所有系統資源都被這些連接占用,可能會(huì )導致無(wú)法建立新連接。在這種情況下,可以考慮減少連接超時(shí)值,這些值控制操作系統維持連接多長(cháng)時(shí)間;這可以使用 Solaris 的 ndd 或 AIX 的 no 來(lái)設置。
前面幾節討論了需要調優(yōu)的四個(gè)系統領(lǐng)域。其中之一是內存。在 Java 應用程序環(huán)境中,服務(wù)器把內存分配給 Java 進(jìn)程,Java 進(jìn)程負責運行應用程序代碼。這個(gè) Java 進(jìn)程就是 JVM,它負責把內存分配給底層應用程序。
在操作系統級上,可能看到 1GB 內存被分配給一個(gè) Java 進(jìn)程。在這個(gè)進(jìn)程內部,JVM 管理堆,堆為新對象提供內存。在創(chuàng )建對象時(shí),對象被放在堆上。在銷(xiāo)毀對象時(shí),它們仍然留在堆上。JVM 會(huì )運行一個(gè)稱(chēng)為垃圾收集 的過(guò)程,垃圾收集標出所有創(chuàng )建的對象,然后清理堆的其余部分供以后的分配使用。在此時(shí),堆可以擴展(如果垃圾收集沒(méi)有回收新分配所需的足夠內存)或收縮(如果滿(mǎn)足特定條件,使 JVM 認為堆太大了)。
根據這個(gè)簡(jiǎn)化的垃圾收集定義可以推斷出,在執行垃圾收集時(shí)系統不會(huì )執行任何應用程序工作。在運行垃圾收集期間,JVM 實(shí)際上會(huì )暫停。因此,許多 Java 調優(yōu)措施都涉及決定堆的最佳內存大小以及調整垃圾收集過(guò)程。
垃圾收集過(guò)程調優(yōu)的基本思路是,了解運行垃圾收集的頻率以及觸發(fā)它的條件,然后通過(guò)修改 JVM 設置盡可能降低垃圾收集的影響。
為了了解垃圾收集對應用程序的影響,首先要收集關(guān)于何時(shí)及如何執行垃圾收集的信息。在 JVM 中啟用詳細垃圾收集日志記錄,這會(huì )開(kāi)始記錄垃圾收集活動(dòng)。在 IBM WebSphere™ Application Server 中,可以在管理控制臺中找到這個(gè)設置:在 Integrated Solutions Console 中導航到 Application servers > server name > Process Definition > Java Virtual Machine,選擇 Verbose Garbage Collection。
還可以用 -verbose:gc 參數啟動(dòng) JVM(這也是 Integrated Solutions Console 選項在幕后采用的方法)。無(wú)論采用哪種方法,JVM 的輸出現在都會(huì )包含垃圾收集信息。
對于啟用詳細垃圾收集日志記錄,糟糕的方面是不同廠(chǎng)商采用的文件格式不一致,甚至在同一廠(chǎng)商提供的不同版本之間也可能不一致。例如,IBM 的 Java Runtime Environment (JRE) 6.0 采用詳細的 Extensible Markup Language (XML) 文件格式。而 Sun Microsystems 的 HotSpot JVM 使用簡(jiǎn)明的單行格式,有時(shí)候需要啟用更多命令行參數,才能得到所需的信息。
啟用垃圾收集器的日志記錄之后,在正常負載下運行應用程序。然后,研究垃圾收集日志??梢钥吹蕉训拇笮淖畛醯姆峙溟_(kāi)始增長(cháng),最終穩定在某一范圍內。然后,可以使用這個(gè)范圍內的某個(gè)值作為堆的初始大小,這會(huì )消除堆增長(cháng)到穩定狀態(tài)導致的初始延遲。
垃圾收集日志還會(huì )指出發(fā)生垃圾收集的時(shí)間以及垃圾收集花費的時(shí)間。如果發(fā)現垃圾收集的運行時(shí)間太長(cháng),可以考慮讓 JVM 使用另一種垃圾收集算法(具體細節取決于 JVM 的版本和廠(chǎng)商)。根據這些時(shí)間戳,還可以計算出系統在垃圾收集方面花費的時(shí)間百分比,可以用這個(gè)指標比較各種 JVM 設置。
如果發(fā)現堆不斷增長(cháng)和收縮,可以修改 MinHeapFree 和 MaxHeapFree 值,JVM 使用它們決定什么時(shí)候擴展或收縮堆。
隨著(zhù) JVM 的發(fā)展,與垃圾收集相關(guān)的性能也會(huì )變化。一定要通過(guò)您的 JVM 手冊了解當前的調優(yōu)參數。
對于在為 WebSphere Application Server 調整 UNIX 服務(wù)器時(shí)應該檢查哪些方面,IBM 給出了一些建議。
首先,確保服務(wù)器具有所需的資源:CPU、磁盤(pán)、內存和網(wǎng)絡(luò )。這些是最基本的。
接下來(lái),了解應用程序的垃圾收集需求并相應地調整 JVM。這可能需要回到前一步,確保具有按所需方式運行應用程序的足夠內存。
確保適當地設置應用服務(wù)器隊列,讓?xiě)梅?wù)器只處理它能夠處理的請求。當 Web 服務(wù)器把請求交給應用服務(wù)器時(shí),它會(huì )進(jìn)入一個(gè)隊列。如果允許太多的連接連接到應用程序,每個(gè)用戶(hù)都會(huì )體驗到糟糕的性能。因此,過(guò)剩的連接應該在 Web 服務(wù)器上排隊,而不要在 WebSphere Application Server 上排隊。
最后,可以使用多種緩存技術(shù),比如數據庫中的預備語(yǔ)句、Enterprise JavaBean (EJB) 技術(shù)和線(xiàn)程緩存。如果不斷清理緩存,從而為新內容讓出空間,就應該考慮增加緩存大小。
計算機的資源分為 CPU、磁盤(pán)、內存和網(wǎng)絡(luò )。調優(yōu)工作應該度量這些資源,然后在應用程序、應用服務(wù)器和服務(wù)器中做相應的調整,確保不出現資源爭用。
JVM 管理自己的堆并通過(guò)垃圾收集過(guò)程清理堆。這方面的調優(yōu)包括確保堆可以增長(cháng)到應用程序需要的大小,以及通過(guò)調整垃圾收集參數避免垃圾收集的影響過(guò)大。
進(jìn)行垃圾收集調優(yōu)的主要工具是詳細垃圾收集日志記錄,這會(huì )記錄每個(gè)垃圾收集活動(dòng)??梢酝ㄟ^(guò)日志了解垃圾收集花費的時(shí)間以及執行收集的原因。
學(xué)習
獲得產(chǎn)品和技術(shù)
聯(lián)系客服