? ? 基于技術(shù)的等待點(diǎn)
??? 基于層次的等待點(diǎn)考慮的是在不同服務(wù)器之間傳遞請(qǐng)求,而基于技術(shù)的等待點(diǎn)關(guān)注的則是在單個(gè)服務(wù)器中如何通過(guò)有效地內(nèi)部工作來(lái)傳遞請(qǐng)求。基于層次的調(diào)優(yōu),類(lèi)似于IBM的隊(duì)列調(diào)優(yōu),只是調(diào)整應(yīng)用的有效第一步,如果忽略了調(diào)優(yōu)應(yīng)用服務(wù)器的內(nèi)部工作,則會(huì)對(duì)應(yīng)用性能產(chǎn)生巨大的影響。這就類(lèi)似于調(diào)整JDBC連接池以發(fā)送最佳數(shù)量的負(fù)載給數(shù)據(jù)庫(kù),但是忽略了檢查執(zhí)行的SQL語(yǔ)句——如果查詢(xún)需要連接十個(gè)表單,每個(gè)表單有一百萬(wàn)個(gè)記錄,則最佳負(fù)載可能是兩個(gè)連接,但是如果我們優(yōu)化了查詢(xún),則數(shù)據(jù)庫(kù)可能支持二百個(gè)連接。深入研究應(yīng)用服務(wù)器和應(yīng)用使用的潛在技術(shù),可能存在以下通用的基于技術(shù)的等待點(diǎn):
????● 池對(duì)象(比如無(wú)狀態(tài)session bean或者其他應(yīng)用放入池的業(yè)務(wù)對(duì)象)
????● 緩存設(shè)施
????● 持久化存儲(chǔ)?或外部依賴(lài)池
????● 通訊基礎(chǔ)設(shè)施
????● 垃圾收集
??? 大多數(shù)情況下,無(wú)狀態(tài)session bean池的大小被應(yīng)用服務(wù)器優(yōu)化,不會(huì)是一個(gè)明顯的等待點(diǎn),除非池大小被手工錯(cuò)誤的配置了。但是也存在一些池對(duì)象必須手動(dòng)配置大小——這些可能成為有效的等待點(diǎn)。當(dāng)一個(gè)應(yīng)用需要一個(gè)池化的資源,它必須從池里獲取一個(gè)資源實(shí)例,使用它,然后釋放給池。如果池太小,所有的對(duì)象實(shí)例都在被使用,則請(qǐng)求不得不等待一個(gè)實(shí)例可用。顯而易見(jiàn),等待一個(gè)池化的資源會(huì)增加響應(yīng)時(shí)間,如果越來(lái)越多的請(qǐng)求被堵塞在等待池化資源,會(huì)導(dǎo)致明顯的性能下降。另一方面,如果池很大,它可能消耗過(guò)多內(nèi)存,對(duì)總體JVM的性能產(chǎn)生差的影響。池的最佳大小需要權(quán)衡,只能在對(duì)池的利用情況做徹底的分析才能決定。
??? 池化對(duì)象是無(wú)狀態(tài)的,這意味著應(yīng)用從池中得到哪個(gè)實(shí)例都無(wú)所謂——任何實(shí)例都行。另一方面,緩存的對(duì)象都是有狀態(tài)的,也就是說(shuō)當(dāng)應(yīng)用從緩存中請(qǐng)求一個(gè)對(duì)象時(shí),它的目標(biāo)是一個(gè)特定對(duì)象。舉一個(gè)很粗糙的類(lèi)比說(shuō)明一下區(qū)別:考慮人們生活當(dāng)中兩種常見(jiàn)的活動(dòng):超市購(gòu)物和接孩子放學(xué)。在超市中,任何收銀員都可以接待每一位顧客,無(wú)論顧客選擇哪位收銀員都可以順利結(jié)賬。因此收銀員可以池化。但是在接孩子放學(xué)時(shí),每一個(gè)父母只想要他們自己的孩子,別的孩子是不行的。因此孩子可以被緩存。
??? 如前面所述,緩存提出了一個(gè)新的調(diào)優(yōu)挑戰(zhàn)。簡(jiǎn)單說(shuō),緩存的目的是在本地內(nèi)存中存儲(chǔ)對(duì)象,使應(yīng)用可以隨時(shí)讀取它們,而不是在需要的時(shí)候才獲取他們。一個(gè)合適大小的緩存可以對(duì)通過(guò)遠(yuǎn)程調(diào)用加載對(duì)象的行為提供明顯的性能改善。但是,一個(gè)不合適大小的緩存,可能產(chǎn)生明顯的性能阻礙。因?yàn)榫彺婢S護(hù)有狀態(tài)的對(duì)象,所以重要的一點(diǎn)是在緩存中存儲(chǔ)最頻繁訪(fǎng)問(wèn)的對(duì)象,同時(shí)保留額外的空間來(lái)處理非頻繁訪(fǎng)問(wèn)對(duì)象。試想如果緩存太小,請(qǐng)求會(huì)怎樣:
??? 1、請(qǐng)求檢查緩存中是否存在某對(duì)象,結(jié)果失敗。
??? 2、請(qǐng)求需要查詢(xún)外部資源獲取對(duì)象數(shù)據(jù)。
??? 3、因?yàn)榫彺嫱ǔ>S護(hù)最頻繁訪(fǎng)問(wèn)的數(shù)據(jù),所以這個(gè)新對(duì)象需要添加到緩存中(它正在被訪(fǎng)問(wèn))。
??? 4、但是如果緩存滿(mǎn)了,必須利用“最少最近訪(fǎng)問(wèn)”算法選擇一個(gè)對(duì)象移除。
??? 5、如果緩存對(duì)象的狀態(tài)與外部資源不一致,則緩存對(duì)象移除之前必須更新外部資源。
??? 6、新的對(duì)象此刻添加到緩存中。
??? 7、新的對(duì)象最終返回給請(qǐng)求。
??? 這是一個(gè)低效的過(guò)程,如果大多數(shù)請(qǐng)求都要執(zhí)行這些步驟,那么緩存肯定會(huì)降低性能。緩存必須調(diào)整到足夠大以最小化緩存的“不命中率”,一次不命中意味著需要執(zhí)行前面提到的七個(gè)步驟,但是也不能太大導(dǎo)致占用太多JVM內(nèi)存。如果緩存需要非常非常大才能滿(mǎn)足性能需要,那么最好是重新考慮被緩存對(duì)象的實(shí)質(zhì)和它們到底是否值得緩存。
??? 類(lèi)似對(duì)象池,外部資源池,比如數(shù)據(jù)庫(kù)連接池,也必須足夠大以滿(mǎn)足請(qǐng)求不會(huì)被迫等待池中的一個(gè)連接變?yōu)榭捎脿顟B(tài),但是也不能太大,導(dǎo)致應(yīng)用浪費(fèi)外部資源。“后退調(diào)優(yōu)”一節(jié)討論了如何決定這些池的最佳大小,但是在本節(jié)的上下文中,牢記它們代表了一個(gè)明顯的等待點(diǎn)。
??? 調(diào)優(yōu)通訊基礎(chǔ)設(shè)施遠(yuǎn)遠(yuǎn)超出了本文討論的范圍,因?yàn)槠渚唧w實(shí)現(xiàn)因產(chǎn)品不同而存在明顯的區(qū)別,這包括諸如MSMQ、MQSeries、TIBCO等主流產(chǎn)品。但是請(qǐng)記住,如果一個(gè)應(yīng)用與某消息服務(wù)器交互,它必須經(jīng)過(guò)合適的調(diào)優(yōu)或者它也代表了一個(gè)等待點(diǎn)。
??? 最后一個(gè)明顯影響JVM性能的等待點(diǎn)是垃圾收集。它不太適用本文中描述的等待點(diǎn)分析過(guò)程(檢查一個(gè)請(qǐng)求,定位導(dǎo)致該請(qǐng)求等待的技術(shù)),但是由于它可以對(duì)性能產(chǎn)生顯著的影響,所以把它列在這里。不同的JVM實(shí)現(xiàn)和不同的垃圾收集策略決定了垃圾收集如何執(zhí)行,但是在很多情況下,一次主垃圾收集(或者說(shuō)標(biāo)記—清除—壓縮垃圾收集)可能導(dǎo)致整個(gè)JVM暫停直到垃圾收集完成。一個(gè)顯著提高JVM性能的辦法就是優(yōu)化垃圾收集。如果想了解更多垃圾收集的信息,請(qǐng)加入GeekCap討論應(yīng)用基礎(chǔ)設(shè)施調(diào)優(yōu)。
已有 0 人發(fā)表留言,猛擊->>這里<<-參與討論
ITeye推薦