性能優化的一點感觸

最近參與了幾個項目的性能優化,總體來說各個項目都有所提升,能夠滿足用戶使用需求,但是這個過程耗費了大量的人力、物力資源成本,主要原因有以下幾點:

  • 系統本身沒有任何參數指標,這一點其實是大多數系統存在的問題,打個比方我作爲乙方給甲方做了一個軟件,交付完成後供甲方使用,這個系統的TPS是多少?硬件配置/用戶矩陣是什麼?系統可靠性4個9還是2個9?你可能會說,我們的客戶要求根本沒有這麼嚴格,能用就行,實則不然,如果說一年沒問題,一年後客戶的用戶數量增長了一倍,忽然發現系統卡頓,幾乎不能使用,客戶找你算賬,這該怎麼辦?誰的原因造成的..... 你說我們給自己公司做的產品,不要求這些東西,滿足當前用戶即可,那我現在問你,你的系統用戶承載量是什麼?當你真的出現用戶數量激增,你該如何應對?

  • 框架標準化,如果一個企業中多個項目使用的框架五花八門,真正出現性能問題的時候,只能大家齊上陣,見招拆招,忙的不亦樂乎,其實收效甚微。

  • 翻譯需求,很多功能邏輯說不通,但又沒法改,爲什麼?客戶要求如此、產品經理設計如此,產品經理也已經不在了,原型設計文檔找不到了,當然這種項目都是比較老的項目,很多公司都會存在此類問題。

  • 灰度發佈系統,深夜一羣人呆在一起發佈一個系統,一起處理bug真的是團隊團結的表現嗎?回家陪陪老婆孩子,好好休息,第二天的工作效率不是更高嗎?

如果現在讓我做一個系統,我應該如何設計?趁着週六有時間就這四個問題簡單聊聊,希望能夠對大家的工作有所啓發。

系統參數

你打開的汽車使用說明書,它會告訴你它在什麼溫度下可以正常工作、最高時速是多少、承客量多大......如果出現問題,儀表盤會給出什麼樣提示,你應該如何規避這些故障。軟件系統也一樣,你的安裝部署手冊裏要告訴別人你的系統需要多大內存、多少硬盤、什麼規格的CPU來支撐多少用戶量。設計文檔的非功能性指標應該包含系統每秒處理事務數量(TPS)或查詢數量是多少、安全性指標等級甚至支持用戶數量;你的管理端界面或者監控系統應該告訴運維人員CPU佔用量、內存佔用量、硬盤使用情況、帶寬使用;閾值告警參數,觸發閾值產生告警,研發人員如何查看日誌排除故障。

說的簡單,這些指標從哪裏得到呢?沒有特別好的辦法,只能通過壓力測試、穩定性測試、安全性測試甚至平時的故障模擬中得到。

確實這些度量指標非常昂貴,甚至要超過你係統本身的成本,即便如此,你要去做,因爲你不去量化一個系統,你就無法管理一個系統,可以想象一下你每天都是在閉着眼睛開車,你永遠不知道您離災難有多近。所以你要說服你的老闆,抵擋住節省金錢的誘惑,認真對待系統指標數據。

當然完全做出這些東西到底有多複雜?我作爲過來人認爲並不複雜,而且能減輕不少後期工作量,想想一個系統不會所有的接口都對性能有要求,所以你只要評估出存在性能瓶頸的接口加以性能測試即可;另外性能測試腳本開發完成後都是複用的狀態,所以不會產生太大工作量,而且又保證了每次上線之前都可以自動化驗證部分接口,這不比人肉點點點香的多嗎?

另外像一些系統層面的參數指標,比如Http調用成功/失敗情況、CPU、內存佔用情況、告警等,可以搭建一套監控工具,比如Prometheus等。完成此類指標的獲取。

如果說我的系統總共就幾個人用、或者這種付出和收益完全成反比,那當我沒說。

框架標準化

框架,通俗來說也就是我們產品/項目架構,就架構本身而言,一定先有設計目標,架構要去幹什麼樣的事情,去完成一個購物網站還是一個管理平臺,存在很大區別;根據設計目標,應該定義出設計原則,這也就是平時經常見到的控制反轉、里氏替換、最小依賴、單一職責等原則,加上清晰的邊界和實現價值(架構做什麼,不做什麼);最後通過使用Gof總結出來23種設計模式加上算法就形成了一套框架。在這個框架的基礎上就可以開發我們的應用。你可能會反駁我們項目五花八門,經常變動,一般架構很難滿足,甚至架構需要經常改動,大概率是框架抽象定義的不夠好,你看看你平時用到的tomcat框架、spring框架,你感知到它的存在了嗎?反而像早期IBM做的weblogic、jboss什麼都做的重量級框架,已被拋棄,所以解耦和抽象再怎麼強調都不爲過。

定義好框架只是第一步,下面就是使用了,就目前國內情況而言,開源項目越來越火爆,所以基本上從網上找找,七拼八湊就行成了一套自己的框架,這本身而言也沒有錯誤,極大降低企業框架定義的成本,但是一個框架通常只能解決某一類的問題,所以前期就需要架構人員進行反覆編寫代碼進行測試和使用,得到這個框架自身的數據,而不是看見別人用的很好,別人多少數據量都可以輕易支撐起來,別人的使用場景很可能跟你不一樣,要不然爲啥市面充斥着五花八門的框架,大多數原因都不能從根本上解決自己的痛點問題。

接着架構人員要參與到編碼中,發現問題及時更正和修改,引導開發人員如何劃分模塊,關鍵時刻做出示例,進而形成自己的開發規範,而不僅僅是站在一個指導者的角色,口頭告訴程序員該如何使用,滿足不了性能指標或者業務一團糟的時候開始考慮拆分,然後拆成幾個微服務也是亂上加亂,根本不能從本質上解決問題。

總結來說,做架構首先要考慮的是自己的需求、目的及邊界、原則、實現價值,最後才考慮技術實現和工具組件,而不是首先擼出一套框架生搬硬套,最後說程序員不會使用,代碼寫的太垃圾。

翻譯需求

通常來說,一般是提出需求,架構人員進行架構設計,產品經理畫出原型設計,開發人員開始設計、開發、提交測試交付。最後一個階段看似已經定型,按照需求完成任務即可。但是人都會犯錯,作爲開發/測試人員不能對照原型、設計文檔翻譯需求,出現問題後,自豪的說,就是這樣設計的,我也沒辦法,你找產品去。但是你有沒有考慮過,即使產品人員改了改需求,最後你不還是照做,受傷的還是自己。所以我們在做任何一個功能的時候都要搞清楚問題的本質,事情的初衷。

你可能會反駁說,我的產品比較強勢,他做的東西面向的是用戶,開發人員是無法理解的,照着做就行了。但我覺着這些並不是理由,如果一個產品說用戶要求的,你可以站在一個用戶的角度去理解,如果是從數據角度,讓他把數據拿出來,如果講不明白,你完全可以拒絕,否則你做出來的東西肯定是四不像。所謂鐵打的營盤,流水的兵,換了幾波人之後完全無法理解這種邏輯,產品如何迭代。你要說你的產品功能過於複雜,大多數是產品設計就存在一定問題,你看看你常用的應用,那個不是簡單易用。

爲什麼要對開發人員強調需求呢?因爲你的需求做的不嚴謹,存在漏洞,都會給後期的性能、再次開發埋下禍根,而且這種問題,越往後解決成本越高。

灰度發佈

相信大家面試的時候經常會聽到面試官問這個問題, 如何保證一個系統高可用?如何做到不停機發布系統?答案也很簡單,負載均衡,當然負載均衡也有很多種,有基於域名重定向、DNS、IP、數據鏈路層的負載均衡,你可以根據你服務自身情況,選擇一種適合自己的。當然你會反駁我說,我的系統就一個副本,不要求高可用,那我會說,你敢白天上線嗎?如果不敢,請乖乖做灰度發佈(金絲雀、A/B、藍綠等等)。

這並不是憑空增加大家的工作量,不知道大家認不認這樣一個事實,軟件發佈通常遵循墨菲定律,往往不好的,一般情況下不會出現的問題,甚至沒有想到的,都會在線上出現。要麼人家都說運維人員都相信玄學,其實倒不是因爲玄學,是因爲存在未知。線上的用戶、歷史數據量往往最多的,也是最全面的,所以線上更容易復現一些問題。通過灰度發佈部署多套,開發/測試人員完全可以在工作時間、站在用戶的角度測試完成後上線發佈。否則直接回退,即實現了測試,也沒有影響用戶使用。

灰度發佈說簡單也簡單,最簡單的你在你的nginx寫幾句lua腳本,便可以把包含特定標識的用戶路由到特定服務。

總結

看完本文後,感覺會有點詫異,說的不是性能優化嗎?不應該講講連接池配置多大、緩存如何使用、系統優化、硬件配置、甚至代碼如何編寫的一些技巧嗎?怎麼扯了一堆沒用的。從某種程度上來說,軟件的性能優化成本往往跟前期的軟件設計成本反比,前期在設計上花費的時間越多,往往後期優化成本就越低。沒有任何組織能夠一開始就做一個高性能的軟件系統,大多數都是隨着用戶和數據的增多演化而來。前期的性能指標、系統架構、甚至功能需求編寫都能夠爲後期軟件性能優化帶來幫助。

推薦

不想凌晨上線的你,不考慮徒手擼一個灰度發佈系統?

Kubernetes入門培訓(內含PPT)

原創不易,隨手關注或者”在看“,誠摯感謝!

本文分享自微信公衆號 - 雲原生技術愛好者社區(programmer_java)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章