VIPKID性能測試方向負責人寧浩然做《千萬級約課系統自動化壓測實踐》主題演講。寧浩然分析了VIPKID在鏈路壓測過程中遇到的問題和挑戰,介紹了自動化壓測平臺如何解決代碼級定位鏈路上的性能問題,以及公司如何在無人值守的情況下完成自動化壓測。他指出,“對于測試開發工程師,最重要的不是為了開發而開發,而是要發現工作過程中遇到的痛點問題,把那些可以重復化的或者可以用機器取代的工作通過技術手段替代掉,這才是我們主要的工作方向。”
以下為寧浩然演講實錄:
大家好,我是VIPKID的寧浩然,很高興在這里給大家帶來本次分享,我分享的主題是《千萬級約課系統自動化壓測實踐》。我會基于VIPKID的特點,分析我們在鏈路壓測過程中遇到的問題和挑戰有哪些,簡單介紹一下開發的自動化壓測平臺是如何解決代碼級定位鏈路上的性能問題,以及我們如何敢在無人值守的情況下完成自動化壓測。
首先簡單介紹一下我們的業務,VIPKID目前的業務是在線教育。簡單點來說,用戶可以使用我們的軟件進行課程預約,在約定的時間內通過視頻的方式完成在線一對一線上上課。我們每周一中午會開放下周的課程預約,屆時會有幾十萬的用戶在短短1分鐘時間內將下周要上的課全部約完,這種搶課模式給我們的系統造成了相當大的壓力。每周一對于我們來講都是一個大考。現在公司成立了專門的供需團隊解決用戶需求方面的問題,目前高峰期的流量已經有了一定程度上的緩解,所以本次分享我們會以業務和系統壓力增長最快的2017-2018年為例,介紹我們是如何扛住每周一次的約課高峰。
從圖里可以看到,我們在一年的時間里系統承載壓力上漲了13倍左右,而單秒的約課量也達到了數千節,每周一這個“大考”,對于我們來說可以說是越來越嚴峻,而留給我們產研團隊的時間永遠只有一周。
挑戰有哪些?首先可以看一下我們的約課鏈路,為了讓我們的系統可以承載更高的壓力,滿足業務的增長預期,我們把鏈路上的每一個環節都做了調整或者優化,這些調整讓我們的系統承載能力有了很大提高,但是在這個調整的過程中,無疑是非常痛苦的。我們上到ELB、SLB下到DB,每一次改動都有或多或少的隱患,這些隱患放到線上都是一種災難,我們通過鏈路壓測的方式把這些問題全部招回,保證我們近兩年約課高峰期的穩定性,近兩年共招回線上性能風險近百例。
總結一下,我們主要面臨的挑戰有以下幾點:1、上線非常頻繁,在座可能會說上線頻繁算什么特點,作為互聯網公司哪家上線不頻繁呢?這里的上線有很大一部分都是服務重構、拆庫拆表優化類的項目,這些改動都會影響我們核心的約課鏈路,所以每次的上線對于我們來講都需要進行鏈路機的壓測,當時平均每周大概需要壓測2-3次,是鏈路級的。
同時由于我們的鏈路比較復雜,性能問題定位也是困難重重,對于我們來講時間就是生命,我們需要在一周的時間內完成系統整體性能提高30%這個指標,這個數據是怎么來的呢?就是我們業務增長最快的一段時間里,每周的業務增長量就是30%左右。雖然我們做了一些整體的大規模的優化,來使我們的系統有一個質的提高,但是每周依然需要對特定服務或者接口做一些特定的優化。從設計再到開發,再到功能測試、到性能測試上線,我們只有一周的時間,這對于我們測試來講,就需要有很高的速度方面的要求。
我們當時給自己提出了一些指標,我們需要在一天的時間里完成數百個接口的準備工作,比如,當天提出了壓測需求,當晚就要完成一個壓測的實施。同時,當天壓測如果發現問題,我們要在當晚就把這個問題做出一個初步的定位,因為我們一般是在周四或者周五進行壓測,如果當天不定位,第二天就沒有時間修復,緊接著馬上就是高峰期了。
我們如何快速的準備呢?這個我會放在后面來說。
從2016年開始,我們對系統進行例行的鏈路壓測,首先會統計周一高峰期的數據,然后確定下周的性能指標及我們的優化方向并進行壓測實施,包括一些問題修復回歸,這是我們每周都在例行去做的。從最開始的人工準備階段,到現在我們已經可以通過平臺進行自動化的壓測,包括自動周一拉取數據、生成腳本、如果有問題我們自動停掉、沒有問題或者發現什么問題自動生成報告,第二天研發和測試的同學來了直接分析就好,后面我會再具體介紹。
對于我們的平臺來講,主要的目的無非是提高我們的壓測數據和腳本準備上的效率以及壓測結果分析的效率。所以我們主要分為三塊,首先壓測準備,主要是壓測腳本和數據的準備。對于腳本來講,我們希望壓測的比例可以和線上高峰期實際接口請求比例是一致的,同樣我們可以通過簡單的配置對系統壓力進行等比的增減。對于一些不想要壓測的接口可以支持將它過濾掉。而數據方面,我們希望壓測數據有足夠高的復雜度和樣本量,同時我們又希望壓測過程中不要影響到線上的真實用戶。目前我們是通過拉取線上NG日志的方式,高峰期時間段、接口請求狀況、響應時間、請求量等等,計算我們分給每個接口的新增數是多少,以此來生成我們的壓測腳本,數據同樣是用高峰期實際用戶請求數據并對這些流量進行打標,在保證我們盡可能模擬線上真實情況的同時,也不影響到線上真實用戶的使用。
結果分析這部分也是在壓測過程中一個老大難的問題,比如,一次壓測出現了一個問題,研發可能會先去NG日志或者是sever日志去查,有各個監控平臺,CPU、數據庫等等,這些數據明明我們都有,但是排查起來對于一線開發或者測試來講常常會不知道如何入手。
我們的壓測平臺會把所有和本次壓測相關的數據全部匯總起來,通過平臺進行分析,然后給出一個定位的結論,我們收集的數據不僅有本次壓測的,還包括往期、線上高峰期的數據,一是看本次有沒有異常,第二也通過對比的方式更精準的定位系統鏈路上的問題。打個比方,比如,整個系統需要承載的壓力是10萬qps,其中一個接口線上要求它到1000,實際上到500的時候可能就不行了,這種問題常常在我們的鏈路壓測過程中十分難暴露出來,因為它對我們系統整體的影響太小了,我們根本就看不出來,但是通過平臺可以很快的通過分析,本次數據的接口響應時間或者是預期QPS和實際QPS把這一塊的結果定位出來,這只是其中一種,還包括主機上面的問題等等,我們的報告不光體現出壓測結果,更重要的是可以把這次出現的問題抽離或者壓測出來,輔助我們快速的定位。
再一個很重要的點是監控,目前運維的監控平臺是基于grafana做的,優點是擴展性、兼容性比較強,可以添加各種類型的監控,但是缺點是它的入口成本或者添加成本比較高,往往要加一個鏈路級的監控,會花費很長的時間,如果改動的話還要讓運維提供,需要他們操作,因為一線人員具備操作這個東西的能力。對于我們壓測來講,其實我們并不需要一個監控平臺有如此好的擴展性,我們更期望的是可以通過一個簡單的配置就能快速的把我們的數據大盤給生成出來,方便我們定位就行了,我們每次關注的點并不會有什么變化,比如主機,就看看cpu、load等等這些值。所以,我們目前的做法是按照目前監控的類型,只要把你的服務名還有它的類型填好就可以快速的生成大盤。
另外一點,就是我們平常所加的監控可能在壓測過程中不一定完全適用,比如平常主機、CPU設成70%就需要報警,因為我認為這可能是代表流量異常的情況,但是壓測過程中可能就把這個數值輕松打破掉了。然后每次的鏈路壓測都會收到大量的無用的報警,其實報警多了和沒有報警就沒有什么區別,沒有人會看所有的報警內容。這樣一些很嚴重的問題往往就會被掩蓋掉了,所以在我們的監控平臺里面會單獨把這部分監控給抽離出來,也就是說每次開啟壓測這部分監控才會啟動,這部分監控又分為報警監控、停止監控,這也是我們做自動化壓測的一個基礎。比如,我們達到某一個閾值,我們認為需要報警通知、需要排查問題。然后到服務器承載不了的時候會自動把它停掉。
如圖,這是我們平臺設計的圖,主要分為四個部分,一個任務調度處理模塊主要負責各模塊之間的調度任務,包括壓測啟停、監控開關等等。壓測這塊主要是接口還有數據方向上的準備,監控和報告服務就是剛才說的開啟監控、停止減虧等等,還有生成報告的服務。數據來源主要有兩個,一個是運維的監控平臺,這塊主要負責拿取各種的像主機、DB、還有一些信息,elk是日志平臺,通過它拉取流量也可以根據線上流量情況進行數據的分析。
下面是我們平臺使用的界面,首先,會先配置一下需要壓哪個域名、哪個時間段的、總的Qps期望是多少,再就是添加一個監控,包括各個監控閾值。這些添加好之后,我們一鍵開始,剩下的工作全是平臺來代替我們去生成腳本、去運行、去監控、去報告分析。
我們的報告維度也是比較多的,包括按域名維度、主機維度、接口維度的,還有一些下游接口的報告,看這個接口它下游的響應情況等等。如圖,這是我們監控的快照,包括主機、數據庫這四部分。這是我們結果分析的報告頁,首先我們會把一些錯誤率比較高、響應時間比較長的一些接口拿出來,可以看它的問題點,點進去可以看它的單個接口,下游或者本層的響應情況。右邊是Qps和RT的曲線,現在大部分的壓測工具生成報告只有最高Qps、平均Qps、平均RT這樣的數據,但是中間出現服務的抖動這種情況是看不到的,這種往往代表服務出現了一些問題,比如一次壓測結果拿了監測值,當我們用線上的量去評估,可能往往帶來的是一些誤區。我們的報告里可以看到本次壓測實際每秒的響應時間的情況和Qps情況,分為按服務級別、按域名級別、按接口級別的。
這是我們一個下游API的調用情況,比如,一次壓測出現了,某個接口出現問題我們可以看它下游的情況是什么樣的,可以把下游的異常接口抽離出來并代碼級定位是在上游服務得哪行調用,和往期比,響應時間增加了,錯誤率高了等等這種情況,我們是通過重新封裝組件來達到這一功能的。
下面來分享一個壓測過程中的實際案例,對于一個讓我們性能下降30%的性能問題,我們在10分鐘內完成了鏈路問題的定位,并且修復上線了,當時情況是這樣的,一次例行壓測發現我們系統的總Qps下降了30%左右,而且當時已經沒有一個很大規模的代碼改動,頂多是一些業務上的需求上線,我們的自動化平臺會第一時間定位出我們網絡服務是入口IO有異常,入口IO已經基本上打滿了,同時接口報告里發現是某一個下游接口響應時間較以往有一個很大的增長,我們可以看到這個接口的下游報告里面,下游調用的某一個接口也是響應時間急劇增加,我們還定位到了接口的調用位置,當時直接去那行代碼發現這個確實是我們本周上線的,當時的情況是多取了一個無用的數據,可能是列表型接口,直接把詳情數據取出來了,因為數據量比較大,直接把服務器的IO打滿了,我們當時把這個無用字段刪除掉了,然后再重新驗證,符合預期。
這種問題其實如果是人工調查可能周期就會比較長,因為像網絡入口IO打滿這種問題,會導致所有的接口響應時間都會增長,在NG層查load來講,每個接口響應時間都增長了,根本很難區分或者很難定位。
我們用平臺不管在數據準備還有結果定位上都大大縮減了人力還有時間,可能會有人問,我們做一個平臺什么時候做合適或者應不應該做?我認為對于咱們各個業務來講,可能不一樣,不一定每個公司都需要一個這樣的平臺。比如,你們的壓測場景是單接口壓測或者單服務,定位問題比較簡單,或者用jmeter做這件事不一定比一個平臺做這件事差到哪兒去,我感覺效果有可能是一樣的,但是比如我們這種頻繁的重復化的壓測需求可能是比較適用的場景,對于測試開發工程師,最重要的不是為了開發而開發,而是要發現工作過程中遇到的痛點問題,把那些可以重復化的或者可以用機器取代的工作通過技術手段替代掉,這才是我們主要的工作方向。
轉載:Testin云測