譯者 | 陳峻
審校 | 重樓
作為開發(fā)人員,我們經(jīng)常會陷入兩難的局面:我們既希望在應用中使用閃亮的新工具或代碼庫,又忌憚在部署到生產(chǎn)環(huán)境之后可能出現(xiàn)的未知問題。畢竟,沒有人希望自己的手機老是在半夜叮咚作響,更不用說來自為了保持應用能夠以多少個9高可用性運行的壓力了。這往往塑造了開發(fā)人員在應用構(gòu)建和編程時具有創(chuàng)新精神,卻在運營場景中過于保守的狀況。

其中,一種最為典型的現(xiàn)象便是—“過度配置(overprovisioning)”,即:在云計算環(huán)境中,為應用的部署配備了過多的算力(通常是CPU和RAM),以確保應用擁有足夠的資源,來啟動或應對運行過程中出現(xiàn)的峰值。顯然,既然是過度,我們就需要設法降低此類過度配置的需求,從而節(jié)省大量且寶貴的云服務資源的支出。下面,我將和您一起探討在Java應用的環(huán)境中如何避免過度的配置。
正如大多數(shù)開發(fā)和DevOps人員切實感受的那樣,在一天或一周之內(nèi),應用的流量負載隨著時間的推移,從來就是不均勻的。在閑時,應用無需為不多的用戶請求提供服務或處理數(shù)據(jù),而在大量用戶頻繁對應用產(chǎn)生高利用率時,應用實例會在如下情況下,無法被及時推送給應用,進而出現(xiàn)不穩(wěn)定的峰值:
其中,后兩個問題會導致應用出現(xiàn)毫無響應的狀態(tài),因此在測試過程中,開發(fā)人員很容易注意到應用的負載上限,以及時擴展所需要的CPU內(nèi)核和內(nèi)存數(shù)量。而為了避免再次出現(xiàn)峰值,他們通常會趨向于過度添加CPU和內(nèi)存的數(shù)量,以求安全穩(wěn)定地滿足用戶需求。例如,開發(fā)團隊往往會配置比已發(fā)現(xiàn)的峰值高出5%到50%的額外云計算余量。
但是,過度的預配置也會增加應用在運行過程中的大量成本。畢竟對于正在運行的云虛擬機而言,固有的CPU(核心或虛擬CPU)和內(nèi)存,通常并不會自我彈性調(diào)整。這就意味著無論應用是否會完全使用到已配置的容量與算力,您都需要為此付費。
為此,我們需要使用合適的策略,來管控過度的預配,以節(jié)省不必要的云計算支出。下面,我將向您介紹“垂直擴展(Vertical Scaling)”和“水平擴展(Horizontal Scaling)”這兩種擴展模型,以及每種模型的具體策略。而且此類策略和技術(shù)既可以適用于跑在云端的應用,也能夠適合本地運行的環(huán)境。
垂直擴展旨在讓應用通過簡單的策略擴展,以處理更多的負載請求。不過它不如后面講到的水平擴展那么靈活。垂直擴展意味著向物理或虛擬服務器上的應用,添加更多的CPU內(nèi)核和更多的內(nèi)存(如果應用屬于I/O密集型,則需要添加更多、更快的SSD存儲)。當然,此類擴展往往需要停止并重啟應用。而有時候這對于應用來說是不可接受的。
多年來,彈性計算(Elastic Compute)一直被奉為可擴展應用開發(fā)的“圣杯”。而水平擴展是彈性計算的基礎。水平擴展意味著通過添加更多的服務器(各自具有一套完備的CPU和內(nèi)存)來增加應用的承載能力,而不是向現(xiàn)有服務器添加更多的CPU內(nèi)核和內(nèi)存。
不過,與垂直擴展相比,水平擴展更為復雜,需要更多的規(guī)劃和更多的外部(對應用而言)設置。而且,由于必須引入路由層,這就意味著會產(chǎn)生更多的處理和網(wǎng)絡開銷,因此其效率不如垂直擴展。
在針對Java應用的水平擴展部署中,我們可以通過自動檢測負載,和啟停應用節(jié)點實例的方式,按需增減資源,進而避免過度的配置。而且,就算在較短的時間內(nèi),出現(xiàn)了被過度預置的資源,其數(shù)量也會很少(主要取決于您的配置方式)。
性能測試通常被認為是一種最困難的測試類型。它需要開發(fā)團隊對整個應用及其所有連接的服務,具有深入的了解。他們往往需要通過全面思考和反復調(diào)整,才能正確地生成模擬生產(chǎn)環(huán)境的負載、以及應用數(shù)據(jù)。顯然,為了與生產(chǎn)環(huán)境的特征保持同步,測試環(huán)境的性能設置是一項勞動密集型工作。
就Java應用而言,開發(fā)人員經(jīng)常會在確定應用峰值性能要求時,通過執(zhí)行三項操作,來實現(xiàn)更加貼近真實情況的配置調(diào)整:
通常,開發(fā)人員需要查看服務器(或虛擬機)的CPU與內(nèi)存的利用率,以確定二者為處理峰值負載所需的數(shù)字。其中,在JVM中,他們可以使用工具去監(jiān)控如下兩項指標,以設置正確的級別:
在從JDK 11到17,再到21的測試中,我們發(fā)現(xiàn)每個JVM版本的CPU使用率都有所提升。與之相對的應用代碼則可能需要稍作調(diào)整,特別是當您的應用原先基于早于Java 11的版本時。
同時,不同的GC算法也能提升云端VM的效率,雖然這在很大程度上取決于應用的內(nèi)存利用率。例如,那些執(zhí)行大數(shù)據(jù)處理與轉(zhuǎn)換的應用,會具有與RESTful應用不同的GC配置文件。
下圖顯示了一個典型Java應用,從JVM的啟動到它是如何隨時間推移而執(zhí)行的過程。在啟動時,由于需要啟動JVM、加載各種類,所以其CPU的使用率較高。之后,該應用框架(如,Spring Boot)相繼進入啟動、初始化并達到“準備處理請求”的狀態(tài)。

請注意圖中峰值上方一行的區(qū)域。該區(qū)域顯示了有多少顆CPU被過度預配置給了該應用的VM部署,以應對突發(fā)性高負載。隨著JVM的實時(just-in-time,JIT)編譯器優(yōu)化代碼的生效,該應用的性能會逐漸提高。也就是說,它能夠使用更少的CPU來處理相同數(shù)量的負載。最終,在JIT編譯器的優(yōu)化效果下,JVM達到了較低的CPU利用率基準。那么,為應用保留下來的富余資源,就浪費了您為其分配的CPU。顯然,這些資金本來是有機會可以被節(jié)省的。
鑒于使用高性能JVM可以讓您減少(或完全消除)過度配置的可能性,我們有必要通過了解此曲線及其對應用的影響,來減少分配給應用VM實例的資源。也就是說,一旦知曉了長尾峰值的所在位置,我們就可以降低其頂線(即“過度配置”),以便分配更少的CPU內(nèi)核,并節(jié)省云計算的租用成本。
我們的應用架構(gòu)隨著從單體模式轉(zhuǎn)為微服務(甚至更小的云服務功能),應用的體積規(guī)模也變得越來越小。雖然這些不同的架構(gòu)各有利弊,但在云服務成本優(yōu)化的背景下,使用水平擴展來達到彈性計算的縮減無疑是最好的實現(xiàn)方式。
應用體積的縮減,也能夠減少需要分配給應用每個實例的CPU和內(nèi)存的數(shù)量。而且,這種增量擴展方式不但實現(xiàn)了更高效的資源使用,也反過來達到了對云計算成本更精細化的控制效果。可以說,部署的單元越小,在縱向擴展時所支付的費用就越少。當然,這里主要討論的是自動化的擴展方式。
說到自動化擴展,它是一種根據(jù)應用負載的增加或減少,自動化地增減應用實例節(jié)點的能力。通過云服務成本的優(yōu)化,我們可以根據(jù)所構(gòu)建的應用群集環(huán)境的不同,采用不同的自動化擴展選項。目前,最流行的自動化擴展平臺當屬Kubernetes。當然,它也給標準的固定分布式集群(fixed-distributed-cluster)部署帶來了不小的復雜性。
比Kubernetes更為簡單的替代方案是容器即服務(CaaS),例如AWS的Fargate、Google的Cloud Run、以及Microsoft的Azure 容器。這些部署服務提供了一些更加簡單的應用部署方法,并通過將Docker容器中的應用提供給服務,來自動處理向上和向下擴縮容。CaaS解決方案的缺點在于,它們的成本會高于標準的VM,并且可能會比托管式的Kubernetes部署的成本還要高。
總的說來,減少過度配置可以幫助我們節(jié)省應用在云服務中的成本開銷。無論您使用上述哪種策略來減少過度配置,了解Java應用的CPU和內(nèi)存配置文件,無疑將有助于您掌握應用在啟動和運行時的性能狀況。目前,有一種Azul Platform Prime不但可以為大中型Java應用部署提供更為高效的高性能JVM,而且具有如下特點:
如果您對本文討論的話題感興趣的話,請參閱IDC的白皮書--《優(yōu)化Java應用性能以改善業(yè)務成果和云成本效率》,以了解更多信息。
陳峻(Julian Chen),51CTO社區(qū)編輯,具有十多年的IT項目實施經(jīng)驗,善于對內(nèi)外部資源與風險實施管控,專注傳播網(wǎng)絡與信息安全知識與經(jīng)驗。
原文標題:How to Avoid Overprovisioning Java Resources,作者:Pratik Patel
本文鏈接:http://m.www897cc.com/showinfo-26-97911-0.html如何避免Java資源的過度配置
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com