资深架构师手把手教你性能优化
圖片來源:pexels.com
孔慶龍,一線架構(gòu)師,具有多年的金融架構(gòu)經(jīng)驗,具備 SOA 服務(wù)化、服務(wù)治理、系統(tǒng)優(yōu)化、分布式系統(tǒng)項目經(jīng)驗。目前關(guān)注于互聯(lián)網(wǎng)金融技術(shù)架構(gòu)設(shè)計、分布式架構(gòu)、微服務(wù)架構(gòu)、DevOps 實踐、大數(shù)據(jù)等領(lǐng)域。
1
? ?
什么是系統(tǒng)優(yōu)化
系統(tǒng)優(yōu)化,一方面是系統(tǒng)化地對 IT 系統(tǒng)或交易鏈上的每個環(huán)節(jié)進(jìn)行分析并優(yōu)化,另一方面是對單一系統(tǒng)進(jìn)行瓶頸點分析和優(yōu)化。這兩方面的優(yōu)化目標(biāo)大致相同,無非是提高系統(tǒng)的響應(yīng)速度、吞吐量、降低各層耦合,以靈活應(yīng)對市場需要。系統(tǒng)優(yōu)化主要在如下三個層面上進(jìn)行。
IT 系統(tǒng)治理層: 這一層面的優(yōu)化不只是性能優(yōu)化,還包括為適應(yīng)業(yè)務(wù)架構(gòu)變化而帶來的應(yīng)用架構(gòu)優(yōu)化(如應(yīng)用分層、服務(wù)治理等)。
系統(tǒng)層: 這一層面的優(yōu)化包括業(yè)務(wù)流程優(yōu)化、數(shù)據(jù)流程優(yōu)化(如提高系統(tǒng)負(fù)載、減少系統(tǒng)開銷等)。
基礎(chǔ)設(shè)施層: 這一層面的優(yōu)化主要是提高 IaaS 平臺的能力(如使彈性集群具備橫向擴展能力、支持資源快速上下線和轉(zhuǎn)移等)。
2
? ?
系統(tǒng)優(yōu)化的方法論、思路和原則
什么是方法論,我個人的理解就是聽起來很厲害,做過的人認(rèn)為是廢話,但可以指明行動方向的理論。下面就根據(jù)多年經(jīng)驗,從系統(tǒng)優(yōu)化的常用方法論、優(yōu)化思路和優(yōu)化原則三方面進(jìn)行簡單分享。
2.1
? ?
常用方法論
常用的方法論有以下幾條。
阿姆達(dá)爾定律(Amdahl Law): 根據(jù)公式 S=1/(1?a+a/n)分析每次對整體效果影響最大的點,并進(jìn)行優(yōu)化。
不訪問不必要的數(shù)據(jù): 減少交易線上的不必要環(huán)節(jié),減少故障點和維護(hù)點。
就近加載,緩存為王。
故障隔離: 不要因為一個系統(tǒng)瓶頸壓垮整個交易平臺。
具備良好的擴展能力: 合理地利用資源,提高處理效率并避免單點故障。
對交易鏈進(jìn)行優(yōu)化,提高吞吐量:減少串行同步調(diào)用,合理拆分(垂直/水平拆分),規(guī)則前置。
性能和功能同等重要: 若交易鏈上有 5 個性能變?yōu)樵O(shè)計階段時的 90%,則整體性能會變?yōu)樵O(shè)計時的 59%。
2.2
? ?
優(yōu)化思路
根據(jù)以往經(jīng)驗總結(jié)出系統(tǒng)優(yōu)化的思路,大致如下:
(1)了解現(xiàn)狀,發(fā)現(xiàn)問題。
(2)確定清晰的優(yōu)化目標(biāo),分析現(xiàn)狀與目標(biāo)的差距并確定執(zhí)行路線。
(3)對系統(tǒng)進(jìn)行拆分,分別對邏輯層(Web 層、業(yè)務(wù)層、持久化層)和物理層(客戶端、網(wǎng)絡(luò)、應(yīng)用服務(wù)器、數(shù)據(jù)庫服務(wù)器)進(jìn)行優(yōu)化。
(4)利用工具對系統(tǒng)進(jìn)行監(jiān)控和測試,并對監(jiān)控和測試結(jié)果進(jìn)行分析。
(5)科學(xué)地對系統(tǒng)進(jìn)行優(yōu)化。
遵循一定的程序: 監(jiān)控/性能測試→分析瓶頸→羅列瓶頸的因素→驗證瓶頸因素 →修改系統(tǒng)→確認(rèn)是否達(dá)到優(yōu)化目標(biāo)。
確定影響性能的因素: CPU、內(nèi)存、I/O、網(wǎng)絡(luò)或其他因素。
找出主要的瓶頸,優(yōu)先解決關(guān)鍵因素,再重復(fù)監(jiān)控或測試驗證。
避免過度優(yōu)化,一次修改一個瓶頸,不要對不需要的地方進(jìn)行優(yōu)化。
提高 CPU 性能: 寫出更快的代碼,設(shè)計出更好的算法,減少短期生存的對象。
提高內(nèi)存性能: 減少長期生存的對象。
提高 I/O 性能: 重新設(shè)計應(yīng)用,減少 I/O 的交互。
緩存為王: 適度緩存,做到最大化發(fā)揮數(shù)據(jù)庫緩存、應(yīng)用端緩存、客戶端緩存的作用。
2.3
? ?
優(yōu)化原則
系統(tǒng)優(yōu)化的原則如下:
在應(yīng)用系統(tǒng)的設(shè)計、開發(fā)過程中,應(yīng)當(dāng)始終把性能放在考慮的范圍內(nèi)。
確定清晰明確的性能目標(biāo)是關(guān)鍵。
性能優(yōu)化是伴隨整個項目周期的,最好分階段設(shè)定目標(biāo),在達(dá)到預(yù)期性能目標(biāo)之后,即可對本階段工作進(jìn)行總結(jié)和知識轉(zhuǎn)移,進(jìn)入下一階段的優(yōu)化工作。
必須保證優(yōu)化后的程序可以正確運行。
性能更大程度上取決于良好的設(shè)計,優(yōu)化技巧只是一個輔助手段。
優(yōu)化過程是迭代漸進(jìn)的過程,每次優(yōu)化的結(jié)果都要反饋到后續(xù)的代碼開發(fā)中。
性能優(yōu)化不能以犧牲代碼的可讀性和維護(hù)性為代價。
3
? ?
性能優(yōu)化
3.1
? ?
常見的性能問題
常見的性能問題大多數(shù)是由于資源不足或熱點資源競爭導(dǎo)致的,下面將從客戶端性能、 J2EE 系統(tǒng)性能和數(shù)據(jù)庫性能三方面進(jìn)行簡單介紹。
常見的客戶端性能問題
常見的客戶端性能問題有如下幾項。
加載慢: 第一次啟動慢或者重新加載慢。
無響應(yīng): 事件突發(fā)導(dǎo)致頁面假死。
受網(wǎng)絡(luò)帶寬影響嚴(yán)重: 因為需要下載大量資源文件,所以在一些網(wǎng)絡(luò)環(huán)境不好的地區(qū)頁面加載緩慢。
JS(JavaScript)內(nèi)存溢出: 頻繁地對對象屬性進(jìn)行操作,造成內(nèi)存被大量占用,最終溢出。
常見的 J2EE 系統(tǒng)性能問題
常見的 J2EE 系統(tǒng)性能問題有如下幾項。
內(nèi)存泄漏:在運行過程中,內(nèi)存不斷被占用而不能被回收,內(nèi)存使用率隨著時間的推移或負(fù)載的增加呈線性增長,系統(tǒng)處理效率隨著時間的推移或并發(fā)的增加而下降,直至將分配給 JVM 的內(nèi)存用盡。
資源泄漏:將資源打開后未關(guān)閉或未成功關(guān)閉而導(dǎo)致的問題。這些資源包括數(shù)據(jù)源連接、文件流等。當(dāng)這些資源經(jīng)常被打開而未能成功關(guān)閉時,就會導(dǎo)致資源泄漏。數(shù)據(jù)源連接泄漏是常見的資源泄漏問題。
過載:過度使用系統(tǒng),超出其所能承受的負(fù)荷。
資源瓶頸:資源被過度使用或分配不足而引起資源瓶頸問題。
線程阻塞、線程死鎖:線程執(zhí)行某段代碼時,無法獲得相關(guān)的同步鎖而造成通信阻塞。
應(yīng)用系統(tǒng)響應(yīng)慢:由于應(yīng)用算法未優(yōu)化,不合理地讀取大量數(shù)據(jù),SQL 缺少索引或存在過多表關(guān)聯(lián)而導(dǎo)致響應(yīng)時間過長,執(zhí)行變慢。
應(yīng)用系統(tǒng)不穩(wěn)定:應(yīng)用系統(tǒng)的響應(yīng)出現(xiàn)時快時慢的現(xiàn)象。
應(yīng)用系統(tǒng)中有各種各樣的異常情況發(fā)生:有些是中間件服務(wù)器拋出的異常,有些是數(shù)據(jù)端拋出的異常。
常見的數(shù)據(jù)庫問題
在以往做核心業(yè)務(wù)系統(tǒng)技術(shù)支持時,遇到的常見的數(shù)據(jù)庫問題如下所述。
死鎖:由于聯(lián)機服務(wù)過早開啟數(shù)據(jù)庫事務(wù),第三方服務(wù)未及時響應(yīng),使得鎖和事務(wù)無法提交而導(dǎo)致數(shù)據(jù)庫死鎖。
I/O 繁忙:由于存在不良 SQL 或業(yè)務(wù)邏輯設(shè)計不合理而導(dǎo)致大量 I/O 等待。
CPU 使用率居高不下:由于高并發(fā)或緩存穿透而導(dǎo)致數(shù)據(jù)庫 CPU 居高不下或忽高忽低。
3.2
? ?
性能優(yōu)化的具體工作
“天下武功,唯快不破”,性能優(yōu)化的首要工作就是提高系統(tǒng)的響應(yīng)時間(響應(yīng)時間 = 服務(wù)處理時間 + 排隊時間)。如圖 16.1 所示的經(jīng)典響應(yīng)時間曲線,我們要做的就是通過優(yōu)化程序來減少服務(wù)時間,通過提高系統(tǒng)的吞吐量減少系統(tǒng)的排隊時間。圖 16.1 中的縱軸代表的是響應(yīng)時間,即服務(wù)時間和排隊時間的總和; 橫軸代表的是到達(dá)率。隨著每單位時間進(jìn)入系統(tǒng)的事務(wù)數(shù)的增加,曲線逐漸向右滑動。隨著到達(dá)率的增加,排隊時間會在某一時刻陡然上升,此時,響應(yīng)時間也將陡然上升,性能下降,而用戶會感到非常沮喪。
圖 16.1
下面通過以往項目中的案例來分析性能優(yōu)化的具體工作。
交易線優(yōu)化
交易線用來從服務(wù)消費者的角度查看交易在各個層面上應(yīng)該完成的功能,以及功能點之間的關(guān)系。功能點之間的關(guān)系用有向路徑來表示,如圖 16.2 所示。
圖 16.2
交易線優(yōu)化的原則如下:
最短路徑: 減少不必要的環(huán)節(jié),避免故障點。
交易完整性: 通過沖正或補償交易等確保交易線各環(huán)節(jié)的事物一致性。
故障隔離和快速定位: 屏蔽異常情況對正常交易的影響,通過交易碼或錯誤碼快速定位問題。
流量控制原則: 可以對服務(wù)通道進(jìn)行流量控制,并結(jié)合優(yōu)先級設(shè)置優(yōu)先處理級別高的業(yè)務(wù)。
超時控制漏斗原則: 盡量使交易線上前端系統(tǒng)的超時設(shè)置大于后端系統(tǒng)。
熔斷和故障隔離原則: 避免由于某個服務(wù)提供者出現(xiàn)故障而導(dǎo)致整個交易線不可用。
隨著架構(gòu)的演變,現(xiàn)在已經(jīng)由豎井式系統(tǒng)逐步發(fā)展為以服務(wù)為單元、可靈活構(gòu)建的分布式服務(wù)體系,如圖 16.3 所示。在服務(wù)治理的過程中,原來的核心業(yè)務(wù)系統(tǒng)被打碎為各種獨立的業(yè)務(wù)組件,一些中間層平臺型系統(tǒng)基于這些業(yè)務(wù)組件和流程服務(wù)逐漸構(gòu)建了業(yè)務(wù)服務(wù),并為前端應(yīng)用的快速構(gòu)建提供業(yè)務(wù)支撐。在這個過程中,服務(wù)識別和構(gòu)建是基礎(chǔ),交易線的規(guī)范是保障,通過交易線規(guī)范可以確定服務(wù)治理的涉及范圍,因為在軟件版本迭代時,很少有人能把系統(tǒng)的全部細(xì)節(jié)都考慮清楚,所以要靠規(guī)范來確定治理范圍,而不是靠人。
圖 16.3
要開發(fā)一個訂單查詢功能 A,服務(wù)整合平臺的 B 和 C 兩個服務(wù)都可以完成此功能的開發(fā),不同的是 B 在 C 的基礎(chǔ)上增加了一些額外的校驗。按照最短路徑原則,A 應(yīng)該直接調(diào) 用 C 服務(wù),如圖 16.4 所示。
圖 16.4
流量控制的目的之一是保證各系統(tǒng)健康穩(wěn)定地運行。一般使用計數(shù)器按照交易類型來檢測交易的并發(fā)數(shù),不同交易類型使用不同的計數(shù)器。當(dāng)交易請求到達(dá)時,計數(shù)器加 1; 當(dāng)請求響應(yīng)失敗時,計數(shù)器減 1。
流量控制是對服務(wù)提供者的一種保護(hù)機制,那么服務(wù)消費者如何避免因為服務(wù)提供者不可用而導(dǎo)致自身不可用,并逐級向交易鏈的調(diào)用方放大這種不可用,最終拖垮整個交易鏈路導(dǎo)致雪崩的情況呢? 服務(wù)的消費方一般可以通過以下 3 種方式來防止“雪崩”,實現(xiàn)對交易鏈路的保護(hù)。
隔離機制:資源池隔離。如果將線程池、數(shù)據(jù)庫連接池等獨立分配,那么即使某類 服務(wù)出現(xiàn)問題也只會影響單獨的資源池。
熔斷機制: 當(dāng)調(diào)用失敗,觸發(fā)預(yù)設(shè)的閾值時,應(yīng)快速返回預(yù)設(shè)結(jié)果,避免大量的同步等待,熔斷偵測請求會定期檢測服務(wù)狀態(tài),進(jìn)行服務(wù)狀態(tài)轉(zhuǎn)換。
監(jiān)控報警: 對服務(wù)調(diào)用狀態(tài)進(jìn)行監(jiān)控并設(shè)置預(yù)警值,在發(fā)生異常時可以及時通知相關(guān)人員進(jìn)行干預(yù)處理,縮短異常影響范圍。
客戶端優(yōu)化
圖 16.5
從 Web 請求時序(如圖 16.5 所示)中可以看出,客戶端優(yōu)化的首要目標(biāo)是加快頁面展 現(xiàn)和響應(yīng)速度,其次是減少對服務(wù)器端的調(diào)用,常見的解決辦法如下:
分析瓶頸點,有針對性地進(jìn)行優(yōu)化。
緩存為王,通過在客戶端緩存靜態(tài)數(shù)據(jù)提升頁面響應(yīng)時間。
通過 gzip、deflate 壓縮來減少客戶端網(wǎng)絡(luò)的下載流量。執(zhí)行壓縮的好處是可以減少 60%左右的文本類文件所占用的空間,但執(zhí)行時需要注意解析 HTTP 請求的, Accept-Encoding 頭判斷是否支持壓縮,并在響應(yīng)中設(shè)置 Content-Encoding 編碼格式。
使用壓縮工具對 JS 進(jìn)行壓縮,減小 JS 文件所占用的空間。
刪除、合并腳本、樣式表及圖片,減少 GET 請求。*無阻塞加載 JS。
預(yù)加載圖片、CSS 樣式、JS 腳本。
按需加載 JS 腳本。
優(yōu)化 JS 處理方法,提升頁面處理速度。
圖 16.6 所示的是某企業(yè)內(nèi)部應(yīng)用系統(tǒng)客戶端的 HTTP 請求監(jiān)控記錄。
圖 16.6
從圖 16.6 中可以看到共計發(fā)送 25 次請求(21 次命中緩存、4 次與服務(wù)器端交互)。從 圖 16.7 所示的統(tǒng)計信息中可以看到: 請求耗時總計 5.645s,進(jìn)行了 4 次網(wǎng)絡(luò)交互,接收到 5.9KB 數(shù)據(jù),發(fā)送了 110.25KB 數(shù)據(jù),使用 gzip 壓縮節(jié)省了 8KB 數(shù)據(jù)。
圖 16.7
通過優(yōu)化后端請求、合并和壓縮 JS/JSP 文件等操作,將頁面響應(yīng)時間優(yōu)化到 2s 左右。
進(jìn)行前端優(yōu)化最好了解瀏覽器原理、HTTP 原理。
服務(wù)器端優(yōu)化
服務(wù)器端的涉及面比較廣,圖 16.8 整理了在進(jìn)行服務(wù)器端優(yōu)化時可能存在的問題,以及所采用的輔助分析工具、分析思路、常見解決辦法。
圖 16.8
(未完待續(xù))
本文節(jié)選自中生代技術(shù)社區(qū)叢書之《架構(gòu)寶典》
精彩文章推薦:
微服務(wù)下,接口性能優(yōu)化的一些總結(jié)
沒做性能優(yōu)化,系統(tǒng)說炸就炸...
螞蟻集團(tuán)技術(shù)專家山丘:性能優(yōu)化常見壓測模型及優(yōu)缺點
螞蟻集團(tuán)技術(shù)專家山丘:性能優(yōu)化的常見模式及趨勢
大神手把手教你Java性能優(yōu)化-江南白衣(加強版)
總結(jié)
以上是生活随笔為你收集整理的资深架构师手把手教你性能优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P1223排队接水
- 下一篇: 17 岁高中生独立开发全球疫情追踪网站火