【NCTS峰會回顧】京東零售侯磊:從鏈路化壓測到流量回放的平臺實踐
2019年10月26日,由Testin云測主辦的第二屆NCTS中國云測試行業峰會在京召開,此次峰會以“AI+未來”為主題,匯聚來自國內外測試領域的知名專家學者、領先企業決策者、高層技術管理者、媒體從業者等,共同探討高端云測試技術,幫助測試從業者了解最前沿行業趨勢,及最新的行業實踐。
會上,京東零售技術與數據中臺測試架構師侯磊做《從鏈路化壓測到流量回放的平臺實踐》主題演講。侯磊介紹了京東在鏈路化壓測方面的實踐以及今年在工具上的演進,并指出,“開源社區星級最高的往往不是技術最牛、最好、最新穎的,而是論壇最豐富、社區最活躍,文檔最全面的。當整個團隊的能力逐步提升后,測試工具要想脫穎而出拼的就是運營了。”
以下為侯磊演講實錄:
謝謝大家,謝謝Testin云測給我這樣一個機會和大家分享。和前兩位講師相比我的主題更細節一些、更專業一點。今天演講的主題是《從鏈路化壓測到流量回放的平臺實踐》。鏈路化壓測去年、前年講過很多次了,去年TID上也做過這樣一個平臺的分享,今天在Testin云測主場不以分享工具為主了,還是說壓測方面的東西,以及今年在工具演進上做了哪些嘗試,也是強業務相關的。開始之前,我先問一下大家真正做業務測試的有多少?做工具開發類的呢?如果都沒有舉手的就是領導了,大家注意一下周圍的領導,可能他們需要挖人了。
我本人做開發出身,對工具平臺會更游刃有余一點,今天還是把PPT做了一些調整。從性能測試開始主要分三個方面,先介紹一下鏈路化測試,再介紹一下我們平臺是如何應對鏈路化測試的,最后是今年一個新的嘗試點,流量回放。
說到流量,錄制的方式其實有很多,我們從很多地方都可以錄制流量,大家也都做很多嘗試,比如java中的AOP攔截、機器運維手段(tcpcopy)、或者從LB層也可以。而今天我所講的這個流量回放還是從全鏈路角度,從公司入口交換機上錄流量,這樣的錄制的和基于應用服務器的錄制還是有些區別的。
首先看鏈路壓測,在京東性能測試有幾個發展階段,最初是線下測試,在這個階段由各個功能團隊執行性能測試,大家用的工具也比較分散,主要用于線下問題的定位、新部署系統的性能的評估,再往后,發現線下的測試不能滿足線上的需求,線下的場景也不能復現線上的問題,同時mock的過程比較繁瑣復雜。之后轉為線上測試,再由線上的單點測試向集群測試過渡。在線上測試的時候,大家都會面臨同樣的問題——寫流量,寫流量就要做系統改造,這也是一個非常復雜,非常艱難的一步,上次分享的時候,大家都在問這樣的問題,系統改造應該從何入手?我們改造的困難在哪兒?這個我在后面也會再提到。再之后,就是一些場景化,我們除了壓單接口、壓單服務,逐漸向組合業務、組合接口,包括剛才陸老師說到的BDD,這樣一個在壓測場景的應用。
現在開始做鏈路化壓測,鏈路化壓測又分為系統的鏈路和業務鏈路,這兩個怎么理解?比如,壓一個服務,這個服務會調我的緩存、調數據庫、調其它中間件,這樣就形成一個基于系統的流量的傳輸,這是天然形成的一個系統鏈路。業務鏈路呢?壓一個接口,這個接口可能會調其他的接口,接口A調接口B,也可能調接口C,B有可能又調接口C,這樣形成一個業務的鏈路。
在這個基礎之上,如果我同時對ABC三個服務進行壓測,或者說從多個入口進行壓測,就會形成一個全鏈路的網狀的流量結構。大家可以看這樣一個圖,如果壓一個APP,它會調它的服務層,這樣從一個入口進行壓測的話會訪問多中間層,最后到持久化。如果從多個入口同時壓測的話,比如壓APP1和web3,service2就可能會成為一個瓶頸。單壓任何一個接口TPS都會很高,在組合情況下,service2可能成為多場景的短板,所以鏈路化壓測就是要找到整個系統里面在全流量進行高峰訪問時,到底哪些系統是短板,哪些應用的資源過剩了,做資源調整。比較典型的是京東開了海外站,海外和國內是有區別的,國內APP是主要的入口,泰國、印尼沒有發展到這個階段,PC就是主要的入口,這樣的流量特點就會造成我們系統的資源分布是不同的,我們在海外站上線之前要對海外站做全鏈路壓測,找到系統里面到底哪些資源需要做調整。因為在項目中,每個業務條線、每個開發都盡可能要更多的資源保證自己的系統不掛,而作為項目管理者,需要統籌規劃,做好資源調整使資源達到平衡狀態,最大化的發揮價值,節約成本。
所以說鏈路化壓測主要是以下幾個意義,首先是做整體流量的評估,我們的系統預期今年的雙十一、618能夠扛住多少量?我系統的短板是什么?其次是根據我的短板怎么再做資源的調配,讓我們的木桶盡可能盛裝更多的水,這是鏈路化壓測的目的。
基于這樣的目的,我們的工具平臺又需要做哪些改進呢?首先看我們的鏈路化壓測的核心需求,海量用戶的模擬,鏈路化壓測區分于以往的單機壓測和集群壓測,我們的目標群體是我們的主站上的所有應用,所以我們也需要有等量的壓力機或者等量的用戶發起流量訪問,海量用戶的模擬是必不可少的。第二點就是鏈路化發壓的時候,壓測團隊是多個團隊一起進行發壓,如果有一條業務線壓測的系統扛不住了,就需要降級或者需要減流量,另一種可能是有一條業務線的壓測沒有達標需要增加的流量,則需要把所有的任務都停止從頭再來,這樣的效率是不可接受的,所以要動態的調整某一個接口、某一些流量的訪問量。第三點就是要模擬秒殺以及復合場景。隨著京東組織架構的調整也經歷過工具的變革,最初是有很多工具,各個業務功能團隊執行性能測試,所以各自選型、各自為戰,用的很多工具都有。第二階段,隨著京東業務量的提升,大促618、雙十一的備戰,組建專職的性能測試團隊,這個在業界是比較少的,有專門性能測試團隊,就有專門的經驗積累以及工具的沉淀,大家選型三款工具,它們各有特點,jmeter上手比較方便。ngrinder是一家韓國的開源工具,這款工具第一次把壓力機資源池、腳本資源池管理起來,這樣的性能工具在項目管理上,知識沉淀上,是有優勢的。gatling發壓效率比較高。但是,這三款工具都不能滿足鏈路化壓測的要求,我們做了一個自己的壓測平臺,也是參考了很多壓測工具的實現方式,這一點還得再說一下,在上次的分享之后,很多朋友都會問,京東的這個平臺什么時候對外開放?開始很高興加了很多微信,聊著聊著發現大家不是真的想做我們的用戶,而是擔心京東什么時候會成為競爭對手?這個我們目前是沒有這樣的計劃的,我們還是一個對內的工具,我們也是希望借這樣的機會跟大家交流工具的實踐,因為我本身是做工具開發的。這個大家可以放心,Testin云測這邊也沒有任何競爭的關系。作為一個商業工具來說,它的門檻還是很高的,對內的測試工具即使功能再完善,可能對于用戶的易用性還不是那么好,只是功能性多一點。
測試工具想在公司內推廣,對公司每個組件、每個功能點都要支持,要支持數據庫、支持消息中間件,測試人員也會提一些需求,甚至要一些智能化的東西,比如,自動尋找備測系統最大的處理TPS,這個是逐漸增加并發實現的,有一些自動停止的條件,比如,錯誤率是多少停止發壓了,響應時間多少就停止發壓。還有一種資源的調配,對壓力機的資源、項目管理、對于測試計劃、測試預警。還有作為一個壓測平臺也需要有一個整個性能測試的生態,包括監控,日志、性能調優的診斷工具,所有這些工具要在平臺里做一個匯總。
因為我是做工具的,如果大家也是做工具的,可能也會遇到這樣的問題,每個業務部門都會做自己的工具,接口測試工具、測試腳本管理、測試用例管理,每個部門都有自己的工具,做完這個工具又會面臨一個推廣的問題,跟同公司或者跟同業競爭的問題。性能測試工具相對于功能來說可能還好一點,因為這個門檻稍微會高一些。比如大家都會做性能測試,也都了解線程和進程,但是讓大家真能說出來在性能測試里面什么時候用多線程并發、什么時候多進程并發,不是那么好回答的問題,所以做性能測試工具的時候,也是有一些難度的同樣的需求,各個部門都會做工具,你的工具有什么突出點?首先一點還是技術的保障、技術的壁壘,這就是forcebot在京東內部的不可替代性。首先是海量用戶的操作,下面我會介紹實現過程。另外一個是動態增減并發用戶數,可以看到如圖,這是模擬雙十一的效果,在雙十一0點的時候響應的請求突然有一個遞增的效果,這就是秒殺活動,這個秒殺會持續一段時間,然后逐漸的減少,過一段時間可能有一個新的二次秒殺活動,這個流量又會上去,再逐漸的往下降,這是一個場景的模擬。為什么有這種場景?因為我們的系統現在做的很智能,我們要動態的縮容、增容,我們在秒殺之后的二次活動,二次洪峰來臨的時候系統能不能扛住新的流量,這也是性能測試里面需要模擬的場景,做這個平臺就需要支持這樣的功能。
如圖這是一個平臺實現的基礎架構,就不詳細說了,其中有一點是任務調度服務,通過它的水平擴展支持海量的壓力機進行并發的發壓。
還是說一點我自身做工具的感想,做工具如果在內部推廣最好有一個護城河。首先就是技術的門檻。如果讓一般的測試工程師來做一些工具的開發,封一個頁面,或者通過運維腳本驅動單機測試工具達到集成的效果,或者用一些開源工具包一層,這是大家最擅長、最容易做的。如果再提高一步做一些改良,例如多線程并發、流式計算,可能對于測試工程師來說這個門檻就稍微高了一點點,這是我作為工具開發的一點兒體會/心得。第二個護城河是當整個測試能力逐步提升后,拼的就是運營和維護了,開源社區星級最高的往往不是技術最牛、最好、最新穎的,而是論壇最豐富、社區最活躍,文檔最全面的。在提升后,測試工具要想脫穎而出拼的就是運營了。
再回到系統里來,這里面有幾個難點,1、海量數據的模擬,多并發就是通過海量的壓力機、多線程、多進程實現。在雙十一要想模擬百萬級用戶,至少需要四五千臺壓力機,每臺壓力機線程、進程也看容器的規格,好一點的機器支持并發多一點,差一點的機器一百并發就到頭了。2、數據的收集,這是性能測試工具都會面臨的問題,在jmeter為了精確計算TB99,會把每個響應時間都生成在文件里面,傳給它的master,這樣就造成了網絡傳輸的問題和計算問題。ngrinder有了進一步的改造,它按秒收集單臺壓力機每個請求的響應時間,做一個匯總,求平均后再交給controller,由controller再進行二次平均,進行計算,當然這個數就有些失真了,所以我們在這里做了一點改進。首先還是數據合并,在壓力機上把每個請求的響應時間都做了匯總,這個匯總不是求平均,而是做了數據壓縮,把每一個響應時間的次數統計一下,把這個key-value的數據傳到我們監控的平臺上,這樣傳輸的數據量變小了,同時在計算的時候,只要對map的key值進行計算就可以了,這是中間的小技巧。
還有作為一個壓測的生態來說,監控是必不可少的,除了對壓力機的監控還有被測服務的監控,監控的內容包括資源的監控還有發下請求的監控,對于性能監控來說一定是秒級的,往往程序里面GC時間很短,在頻繁GC的情況下,壓測圖形的秒級監控會形成一個鋸齒狀。另外在GC的時候,還有可能TPS就會掉0,掉坑,這種鋸齒狀的處理能力可能會造成線上的問題,所以壓測監控一定要按照秒級監控。另外一個要注意的是,發壓端與被測端對比。有時候出現這種場景:研發人員很自信:我的監控數據很好、響應時間OK、可用率100%,但是從發壓端來看,發壓端真正是用戶感知的,收到的響應時間跟慢,也有很多time out,但是發壓端的監測是感覺不到的,這樣的問題就需要再定位這是通過對比出來的。這種問題的原因有很多,比如網絡傳輸,序列化和反序列化、系統資源的抖動等等,這就需要具體問題具體定位,這個對于初級性能測試人員是往往容易忽略的問題。
講完工具,再看看京東是怎么做鏈路化壓測這種實踐的,怎么利用forcebot平臺做全鏈路壓測的?首先定義一下壓測的目的:對容量整體的評估,對資源再分配;第二點看壓測方式:我們的軍演是把壓力機部署在CDN上,通過外網模擬真實用戶,這樣的好處是壓測鏈路比較長,包括公司負載均衡、網關、安全都壓到了,但是這套實施的難點就是數據流量的識別,到底哪些是測試數據,這是千萬不能影響線上環境的,也不能給線上帶來臟數據,數據的改造是每一個公司都要面臨的問題。京東做這件事做了一年多,到現在也繼續在持續改造著,上次講完很多朋友都在問京東是怎么做的。我再來解釋一下,最重要的一點是在公司領導層面達成一致。為了一個質量的改進或者質量的驗證,可能會犧牲業務開發的時間,公司高層一定要達成一致意見后再往下推,在推的時候建議各個業務條線架構師配合,如果讓測試人員做技術改造可能有點困難,但是測試人員比較適合做推動者和倡導者,因為改進的是我們的質量,是跟我們的工作息息相關的,可以提高測試效率和效果。最后一定要每周做例會、回顧、周報什么的,通過項目制,把系統改造作為很重要的事推進下去。
如圖,我們是這樣做的打標流量識別,首先在測試之前先準備一些測試數據、測試帳號,發壓的時候需要打標,因為是模擬用戶行為,所以一般都是HTTP請求,第一層服務識別這個標再進行RPC透傳。這也是看業務系統如何改造,如果有能力的話最好在RPC框架基礎上做流量識別、流量隔離。如果不方便從業務層面改造識別也是OK的,改造方式其實有很多,有可能配置一個影子庫、影子中間件,有可能就寫進一個打標的數據,事后再進行清理,這些都是可行的辦法。在京東我們也是每一條線處理的方式有區別。
最后看鏈路化壓測,每年的雙十一、618都會做鏈路化壓測,這個壓測前前后后可能從準備到最終實施要一周多的時間。準備的時候要確認壓測范圍、確定好流量到那個環節就會停止住了,或者說是有哪些入口、哪些系統需要參與壓測對于中臺來說,是否需要補量壓測場景的設計和評審、數據的準備,這就需要花很長的時間了。
第二步要在壓測前,把我們的腳本還有我們的數據準備好,壓測池的資源分配、壓測數據提前錄制好、準備好,分發到壓力機上,因為這個數據往往都是很大的文件,線上錄制也好,構建生成也好,要提前同步到壓力機上,實時拉取可能會影響效果。還要準備好我們要壓什么、緊急預案是什么、發生問題第一聯系人是誰等等,在壓測前一天晚上,要準備好小流量的驗證,可以先試壓一下,最后再線上流量的驗證。實施階段,我們一般是線上扛量用一個機房,壓測用另外一個機房,壓測流量需要適時調整,還有降級演練,最后還要把壓測成績單進行匯總。這個步驟每年都會很費時、很費力,從數據準備到腳本驗證再回放,其實回放可能不會很長時間,但是前期的數據準備、構造會很耗時。
這就說到全鏈路的一個痛點,也就是我們為什么做流量回放,這是今年我們想的一個平臺2.0的演進。
作為平臺開發來說,鏈路化壓測做完以后下一步做點什么?業界都會想到自動化、智能化、常態化,這樣的 title很大,但是怎么做到呢?我們首先想到從數據的準備到發壓做成自動化,就是流量的錄制和回放。不再需要寫腳本和準備數據,這樣從真實環境上錄制流量,當然這個前提是,業務改造一定要相當的完備了,我們寫的流量到底能不能去識別?這個是很必要的。其實做流量回放在京東也是有背景的,在618今年也發生這樣一件事,之前軍演準備的時候,我系統處理的TPS可以達到很高,但實際上在流量高峰的時候,發現還沒有到達這個TPS,系統資源CPU就已經耗盡了。后來,分析原因還是壓測場景設計的不到位,比如,同樣是一個查詢用戶的接口,用戶信息多和用戶信息量少,這個對于系統來說處理是不同的,我們準備壓測場景還沒有完全覆蓋住真實的線上狀態,所以這也是驅動我們必須要做這么一件事的原因:真實的線上的流量回放。
另外一個方面,剛才也提到了,流量回放不僅僅是單機對于單一應用的回放,是中臺和前臺體系所有入口流量通通進行回放,這個在回放過程中天然形成一個配比關系。以往我們的配比關系都是專門分析出來的,例如同一個系統里的三個接口,配比1:3,是通過分析日志,或者分析以往的流量得到的。而流量回放的時候,這個比例是天然形成的,不用再參考、不用再設計了。這是一個巨大的方便優勢。;
第三是切實做到提效,我們想做常態化的壓測,想把這種軍演、鏈路化壓測成為常態化,除了系統改造,還要實施的很方便,錄制數據不需要研發配合,不需要在應用端抓log,不需要改java代碼攔截流量數據,回放的時候也不需要再寫腳本了,這是一個常態化或者說自動化的前提。其實從入口上錄的流量還有一個好處:不再依賴于被測系統,不再依賴于線上應用。以往我們對線上應用的log錄制的話,在大促的時候可能是不敢打開的,因為會影響線上的性能,但是如果我們從入口交換機分光出來的流量對業務是完全無侵擾的,可以隨時隨地的錄,這也是它的好處之一。
最終達到這樣一個效果,線上流量錄制,然后放在數據中心再做壓測流量的回放。
如圖,這是我們實現的一個架構,其實我們也在實踐階段,方案并不是很完備,更多實現細節我也就不再詳細的介紹了,主要還是這樣幾個模塊,抓取模塊從分光器上把流量抓取,到一個性能非常好的消息隊列里面,之后再增加一個安全模塊。線上數據安全性問題是非常重要的,在互聯網行業,安全再怎么做都不會過分,因為用戶安全可能會有各種各樣的問題。最后落盤到京東一個分布式系統里面,大家可以用自己公司的文件系統,這個加密后的數據也可以放到內網回放,甚至用于功能回放都是OK的。具體怎么用,依賴于域名的過濾,根據自己的系統適配就行了,回放的時候可以用個固定的腳本,把錄制的東西當作參數化文件進行發壓。
最后做一個比喻,流量錄制回放相當于蓄水池的概念,用幾個小時的時間把線上數據錄制下來集中存放,然后再用很短的時間集中釋放,達到模擬洪峰來臨的效果。今年在雙十一備戰上我們的流量錄制已經在開始用了,效果還是可以的,很多業務的配比關系直接用這樣的真實數據了,業務的測試也比較輕松了,不用再寫很多腳本了,也不用再向研發要這種參數數據了。
最后有一點想說的是,“醉里挑燈看劍,夢回吹角連營。”線上各種各樣的狀態牽動著測試人員的心,希望大家還是用自己的技術改變公司的質量文化、質量氛圍,從自己做起。謝謝大家!