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