背景
傳統效能測試更多的是以事務為核心,更多的是由單個或者多個事務構成業務場景進行壓測。全鏈路壓測指完全引入相關聯的系統,儘量真實模擬線上硬體環境,更多的是以請求為核心,完全模擬真實請求流量,通過引流等方式進行場景的模擬進行壓測,更多的適用於業務鏈路較長的交易。全鏈路一直是效能測試中的難點,其包含系統越多測試難度就越大,系統架構中每增加一層的監控內容就會給分析帶來幾何倍數的難度。因此,微服務架構下的效能測試的重要性就不言而喻了。
微服務架構下為什麼做全鏈路壓測
微服務系統系統間呼叫關係複雜,當出現業務流量暴漲的情況從CDN、閘道器接入、前端、快取、中介軟體、後端服務、資料庫整個交易鏈路都會面臨巨大的訪問壓力,此時業務系統除了收到自身的影響還會依賴其他關聯絡統的情況,如果某一點出現問題,系統會累加問題並影響到其他其他系統,到時候是哪個系統出問題誰也說不出清楚,比如當某系統MQ開始出現積壓,下游系統處理能就可能會變慢,當MQ吃掉記憶體並造成當機,整個鏈路交易都會停止。
微服務架構下全鏈路壓測的難點
如果在測試環境進行全鏈路壓測,最大難點在於無法評估使用者從客戶端登入到完成交易的整個鏈路中,系統能的最大承載能力是多少。如果無法承載生成中的流量造成系統當機,就會有災難性的後果。所以在測試環境進行全鏈路要結合歷史生成流量,併合理做出業務增長預估,如果能滿足此流量可以判定為生產環境滿足效能要求。當然,這只是權宜之計,如果在生產環境做全鏈路壓測不會出現此情況。
另外,全鏈路壓測涉及的微服務模組多,開發組多,各組開發人員又各負責自己的模組,因為版本升級塊,業務層架構變化也快,很難能瞭解清楚最新的架構,如果漏掉一個系統的呼叫關係,分析就會變得非常困難。
軟體的版本控制問題,因為版本升級快,造成測試環境與生成環境程式碼版本不一致,資料庫表結構和索引不一致的情況。這種情況會造成測試結果不準確,重複測試。多系統更難控制此情況。
微服務架構下如何開展全鏈路測試
開展全鏈路壓測,除了傳統效能測試的需求調研、環境準備、指令碼開發、資料預埋、場景設計、場景執行、應用監控分析、瓶頸定位、瓶頸修復、迴歸測試、結果整理、輸出報告等環節外還要加入分析需壓測業務場景涉及系統和協調各個壓測系統資源兩個環節。
1、梳理核心鏈路
在壓測前我們一定要首先分析清楚需要壓測的業務場景,只有分析清楚了業務場景才能梳理出來涉及的相關係統,分析清楚後也可以更快的找到效能瓶頸進行系統優化。這個工作一般是由架構師來梳理並確認涉及的相關係統,梳理清楚後就可以反饋給壓測負責人進行人員和資源的協調了。
2、壓測資源協調
在全鏈路壓測過程中,最難的工作其實不是系統優化、壓測環境搭建等技術工作,最難的是壓測資源的協調工作。這裡的資源不單單指壓測硬體、軟體、環境等資源,還包括了人力資源。
3、構建資料
資料的真實和可用是保證壓測結果的關鍵,儘量使資料多元化,引數重複性低,可以採用生產資料脫敏的方式。資料的真實性可以保證更真實的模擬生產資料流量。資料的真實不光指發起的資料,測試資料庫的鋪底資料量也要與生產一致。
4、流量監控
搭建流量監控平臺,收集生產各種業務的流量,統計資料,按比例進行流量回放。
5、容量評估
首先知道容量目標是多少,比如全部交易量預期目標每天1億筆,按流量平臺監控到的業務佔比進行壓測,這樣我們可以清楚在哪個節點應該增加多少機器,既能保證系統的穩定又能避免浪費。容量評估不是一步完成的,目標需要結合歷史資料和公司現有業務規模。第一步先按現有環境摸底測試,再逐步增加或減少機器,迴圈多次,最後達到精準的容量評估。
微服務架構下全鏈路壓測優化
1、單系統優化
把鏈路中逐個環節儘量切分成小塊,粒度越小越佳,單粒度分析,涉及其他系統加擋板,這樣可以基本解決所有效能問題。缺點是效能週期長。
2、架構優化
分析系統架構,在硬體資源不飽和情況下儘量減少架構層。筆者在測試中遇到一個案例,A系統呼叫加解密伺服器,A系統因特殊原因執行緒固定300,不能增加執行緒,併發執行緒為300時,A系統伺服器CPU為60%,TPS為370左右,CPU資源不飽和,加解密伺服器cpu為50%,也不飽和,但因A系統不能調整執行緒數量,所以把加解密服務的包部署在A系統上,此時300併發,A伺服器CPU為100%,TPS為700左右。這樣的好處是減少了一層系統呼叫的連線時間,資料傳輸時間,又能使硬體充分利用,減少硬體的浪費。
3、業務優化
很多開發人員都會將優化思路集中在架構層面,但是很多時候從業務流程上進行優化效果可能更好,而且提升的效果會非常明顯。業務優化不包括業務流程本身,還包活實現業務的程式碼邏輯,此優化場景多用於跑批業務。
微服務架構下分析系統瓶頸
下面我將分享在效能測試中,常用的具體分析系統瓶頸的幾個方法。
應用系統從效能角度分為CPU密集型應用和IO密集型應用,調優的目標是讓硬體達到瓶頸而不是軟體達到瓶頸,最直觀的體現就是TPS上升和監控到的CPU和IObusy使用率達到100%。除非有特殊要求,否則儘可能使硬體使用率高。
CPU不飽和原因有很多,最常用的分析手段是檢視執行緒資訊。
1、 jps命令檢視java程式pid
2、jstack -l 5599 > 5599.tdump 把執行緒資訊存進一個字尾為tdump的檔案裡,這裡字尾txt也可以,我習慣用jvisualvm開啟,所以字尾是tdump
3、sz 5599.tdump 把檔案下載到本地
4、開啟檔案,檢視執行緒資訊,有三種情況:
4.1. 如果執行緒都是RUNNABLE狀態,此時CPU利用率依然不高,說明執行緒池業務執行緒數量少,加大執行緒池執行緒數量。
4.2.如果執行緒狀態是BLOCKED,要查該執行緒等待的鎖編號。
4.3.根據鎖編號找到持有鎖的執行緒,再根據資訊分析程式碼問題並優化。
此應用CPU利用率上不去的原因是因為需要壓縮的檔案過大,壓縮時間長,導致其他執行緒都在等待該執行緒釋放鎖,CPU同時間只能處理這一個執行緒,所以利用率低。
5、如果執行緒狀態是WAITING,要分析是什麼原因導致執行緒等待:
這個執行緒是因為logback為同步執行緒鎖,執行緒等待日誌寫入硬碟,導致CPU利用率上不去,只要把logback改成非同步就可以了。
6、IO的問題有兩種情況,一種是CPU等待IO;一種是單個磁碟IObusy達到100%,其他磁碟空閒。第一種情況可以採用快取、非同步的方式去解決,這樣能解決大部分效能問題。這裡主要介紹第二種情況,第二種情況可以進行業務層面的IO分散來保證。就是把寫入一個磁碟的檔案分散寫到多個磁碟上,這樣就可以緩解單個磁碟的壓力。對於效能人員來說,要定位到具體是哪個檔案導致的IO繁忙程度高。在程式碼的邏輯清晰的情況下,是完全可以知道哪些檔案是頻繁讀寫的。但是對效能分析人員,通常是面對一個不是自己編寫的系統,有時還是多個團隊合作產生的系統。如果可以迅速地把問題到一個段具體的程式碼,到一個具體的檔案,那就可以提高溝通的效率。
iostat命令可以發現IO異常。iotop可以定位具體哪個程式導致io異常。但要定位到具體檔案,我們需要先了解一個檔案的重要屬性:inode。
理解inode,要從檔案儲存說起。檔案儲存在硬碟上,硬碟的最小儲存單位叫做"扇區"(Sector)。每個扇區儲存512位元組(相當於0.5KB)。作業系統讀取硬碟的時候,不會一個個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次性讀取一個"塊"(block)。這種由多個扇區組成的"塊",是檔案存取的最小單位。"塊"的大小,最常見的是4KB,即連續八個 sector組成一個 block。
[root@cdhslave1 ~]# tune2fs -l /dev/sda3|grep Block
Block count: 66891008
Block size: 4096
Blocks per group: 32768
複製程式碼
檔案資料都儲存在"塊"中,那麼很顯然,我們還必須找到一個地方儲存檔案的元資訊,比如檔案的建立者、檔案的建立日期、檔案的大小等等。這種儲存檔案元資訊的區域就叫做inode,中文譯名為"索引節點"。inode包含檔案的元資訊,具體來說有以下內容:
1. 檔案的位元組數
2. 檔案擁有者的User ID
3. 檔案的Group ID
4. 檔案的讀、寫、執行許可權
5. 檔案的時間戳,共有三個:ctime指inode上一次變動的時間,mtime指檔案內容上一次變動的時間,atime指檔案上一次開啟的時間。
6. 連結數,即有多少檔名指向這個inode
7. 檔案資料block的位置
通過inode就能找到具體檔案,監控inode,我用SystemTap這個工具。
SystemTap是一個診斷Linux系統效能或功能問題的開源軟體。它使得對執行時的Linux系統進行診斷調式變得更容易、更簡單。下圖是Systemtap的工作原理:
Systemtap的執行是在核心層面,而不是shell層面。Systemtap自帶的examples中有監控IO的例子,以iotop.stp為例,執行的結果是:每隔5秒列印讀寫總量排前10位的程式。先寫一個命令dd bs=64k count=40k if=/dev/zero of=test oflag=dsync,這個命令是每次從/dev/zero 讀取64k資料,然後寫入當前目錄下的test檔案,一共重複4萬次。執行命令後開啟iotop.stp監控,如下圖:
可以看到讀寫最多程式。但是現有指令碼不能看到dd命令讀檔案和寫檔案的inode,需要自己擴充套件一下指令碼,指令碼擴充套件後如下圖:
這裡就可以看到我們讀檔案的inode為4072,寫檔案的inode為15,通過find / -inum命令可以找到具體寫哪個檔案。
總結
本篇介紹了全鏈路壓測的概念,微服務架構下全鏈路壓測的意義、難點以及如何做全鏈路壓測,最後給出系統瓶頸分析和調優建議和方法。