我早期做性能測試,大概在99年。給一個銀行做性能測試,因為其中很大的一個部分是我們開發的。于是自己寫了一個程序,來給後台系統加壓。
大概在2001年,我們做了兩外一個系統,跑在aix上面,性能很差,我幫開發團隊去看一下問題,結論是調度過度,架構不合理(組件模塊劃分的過細)。調優之後,性能提升了大概100倍。後來去給客戶做poc,客戶還嫌慢,說明調優還不到位。再後來又做了一次調優,性能才正常。所謂的正常,就是跟使用tuxedo相比,基本上性能持平,一個數量級。
從性能問題來看,大概分成幾種情況:1,網絡帶寬問題;2,某個節點處理能力(就是tps差)不行;3,流量配置不合理;4,鍊路設計問題。
先說網絡帶寬問題。以前的老系統,特别是銀行的,一般情況下oltp都不會有帶寬問題,因為根據oltp的标準,一個請求包在1-2k,響應報文在4k之内,除非線路很差,一般都不會有。從現在的情況來看,更不會有網絡問題。
我遇到一次網絡問題,是由于病毒占用了大量的帶寬,阻塞了。特殊的情況在于報表下載。如果所有的用戶,在某個時間點上都下載報表呢?也會有擁堵。
實際上,隻要根據tps和一次請求占用的流量大小,來計算一下,就知道整個的帶寬是不是有問題。
比如,一次請求的數據,假設是50k,tps是1000,那麼帶寬需求是:1000*50k=50M。還要考慮上行帶寬還是下行帶寬,請求是上行帶寬。
此外就是一些網絡上傳輸的圖片很容易占用帶寬。
再說流量分配不合理。某個客戶有多個節點,使用nginx來做負載均衡,由于配置錯誤,導緻90%以上的流量都分配到其中一個節點,導緻性能嚴重不達标。這種就需要使用全鍊路分析,看兩個不同節點的cpu占用、帶寬,很容易發現問題。流量分配不合理,主要是配置問題。因此全鍊路跟蹤監控工具非常重要。
近些年,由于系統越來越複雜,已經從C/S、B/S架構的兩層結構,發展到三層結構、多層結構。
在業務處理的每一層,如果出現問題,都可能出現性能瓶頸,所以,我們首先要定位,是哪一層出現了問題。
鍊路設計問題。有時候,由于應用系統設計不當,導緻産生了很多多餘的鍊路。比如可以使用三次通訊來解決的問題,結果使用了5次,多出來的兩次很容易造成錯誤和性能問題。當然性能測試隻能夠發現問題,解決問題還要看設計鍊路的人。
這裡面就涉及到一個問題:架構。網絡架構、系統架構、IT架構等等。話題太大,就不展開贅述了。
最後,我們看節點處理能力問題。其實,節點又分成很多種類,比如存儲、比如數據庫。這一類的問題,一個要看數據庫的配置和資源情況,另外一個就要看表結構、索引,重要的一點是程序。
數據庫問題,常用的是看資源是否占滿,比如io,比如cpu等資源是否過高。如果不高,但是又很慢,大多數是程序和結構問題。
最後看代碼,也就是應用程序。應用程序優化,往往是系統的核心,絕大多數的性能問題,都是由于代碼編寫不當引起的。
從我自己的經驗來看,主要是幾大類:
1,錯誤的數據結構和算法。
某個項目,做了一個插入操作,結果花費了一分鐘。我仔細看了一下代碼,其實算法并不是很複雜,就是在數據庫中構建了一個tree,然後把某個節點插入。
但是很慢。本質的問題在于,程序員把數據庫當作内存來使用。内存的訪問速度很快,數據庫查了幾個量級。
所以使用錯誤的數據結構,是很多問題的核心。這種情況就需要修改架構和算法才能夠解決。
2,算法問題。
另外一個項目,也是操作很慢。去看了一下,沒有架構問題。但是,有很多循環嵌套。關鍵是,在循環裡面去訪問database。
千萬不要在循環裡面去訪問db,幾乎是百分之百的慢。
循環嵌套。就是多層循環,裡面還嵌套數據庫訪問,程序員是想作死。
3,block和輪詢。
block,阻塞和輪詢,是我們訪問資源的兩個方式。block的問題會造成程序挂起,但是挂起并不消耗cpu,但是會占住一個線程/進程。
輪詢很快,但是頻繁的輪詢會導緻cpu上升。
所以要評估你的算法,當訪問資源的時候,是使用block還是輪詢。
好像這一直是個問題,需要大量編碼經驗才能解決。
這也就是說,為什麼沒有大量的編碼經驗,吹噓做架構師,很容易犯低級錯誤。
4,資源忘了釋放。
這是很多闆磚程序員容易犯的錯。
5,分清楚系統調用和一般的調用。
系統調用,system call,會調用操作系統的核心,訪問核心資源。所以,你看起來是一個函數,但是這個函數會導緻你的系統很慢。
當然現在使用的語言遠比c這樣原始的語言高級,使得程序員分不清系統調用和一般函數。
經常遇到的問題是,内存分配。當你頻繁訪問内存,一些算法是從操作系統的堆來申請内存的,導緻系統很慢,而且會産生很多内存碎片。
所以分清楚系統調用和一般函數,非常重要,盡量避免使用系統調用,特别是頻繁的調用。
6,程序執行效率不高。
這個其實有很多算法,比如循環展開等等。你需要去了解編譯器、cpu的指令序列是如何工作的。
cpu最怕的指令是jump,就是程序裡面的循環和判斷(if-else)。
如果知道這些,解決大多數性能問題應該不困難。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!