天天看點

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

作者:Civen

當業務越發複雜、系統規模越來越大,以及外圍資源依賴得越來越多時,系統中可能存在的各種不确定性因素也會随之被放大,甚至一個細微的錯誤都有可能導緻交易系統出現雪崩。是以壓測成為開發人員在大促前夕檢測系統短闆、瓶頸最有效的手段,為相應的風險點制定出有效的預案,才能夠避免大促時不被那些不确定性因素所帶來的影響打個措手不及。

驗證系統所能夠承受的最大負載是否接近于預期,是否經得住大流量的沖擊,絕非是一件易事。有過分布式系統開發經驗的同學都應該非常清楚,簡單對某個接口、子系統進行壓測,并不能夠準确探測出系統整體的容量水位,這是由分布式系統與生俱來的複雜性決定的,并且對環境、目标都有着極為嚴苛的要求。近些年,全鍊路壓測似乎備受追捧,基本上各大網際網路企業,比如:阿裡、京東等都會在大促前夕利用自研的“軍演系統”線上上進行壓測實戰演練,其目的就是確定大促來臨時核心鍊路的整體穩定。本章筆者會重點為大家介紹,筆者所在企業是如何在大促前夕對線上環境實施全鍊路壓測,以及如何做到有指導的在大促前進行容量規劃和性能優化,讓系統堅如磐石。

1.1 為什麼要線上上實施全鍊路壓測

在為大家介紹本章主題之前,請大家首先冷靜思考下,大促前夕我們需要考慮哪些事情?或者說有哪些事情是必須要做的,盡可能做到心中有數,不打無準備之仗。筆者總結了大促前夕最基本,同時也是最棘手的2項備戰任務:

● 評估機器擴容數量,

● 驗證系統整體容量是否能夠有效支撐所預估的流量峰值。

大多數網際網路電商平台在剛開始的時候,由于流量不大、機器數量不多、以及經驗上的匮乏,評估需要擴容多少台機器來應對突增的活動流量,往往采用的做法都是非常“簡單粗暴”的,那就是不管三七二十一,腦子一拍,以平時的機器數量為基數橫向擴容十幾倍、幾十倍。但随着使用者規模的線性上升,這種評估方式必然是不可取的。

首先,大促産生的流量峰值必然是平時的幾十倍,乃至上百倍,待庫存消耗完後,流量會急劇回落至正常水準,換句話說,峰值的持續時間并不會太長,對于一個稍微有點規模的電商企業來說,日常運維的伺服器數量都會維持在近千台左右,如果還是按照這種方式來評估活動時所需的機器數量,必然會造成許多不必要的資源浪費(一些外圍系統隻需要少量擴容,因為壓力主要都集中在核心鍊路上)

其次,存儲系統的伸縮成本是非常“昂貴”的,并且很多服務的擴容數還受限于底層連接配接資源,是以務必需要采取一種更為合理的評估方式。那麼應對大促時的機器數量究竟應該如何評估呢?簡單來說,我們首先應該梳理清楚整個業務系統中哪些才是真正的核心鍊路,然後得出單機的最大容量,并根據活動的GMV(成交額)來推算出理論上需要擴容的機器數量。在此大家需要注意,推算出來的理論值,還需要進行充分的驗證,接口的短闆效應絕對不是靠評估出來的,隻有當系統整體的負載處于較大壓力時才會暴露,比如:慢速SQL、連接配接資源耗盡等。

根據活動的GMV推算出理論上需要擴容的機器數量後,最好的驗證方式就是壓測,因為隻有在系統經曆過實際壓測後,我們才能夠清除系統整體的真實容量水位,接口的短闆效應也隻有在壓測後才能進行有效規避。

筆者所在企業的全鍊路壓測之路走得還是比較艱辛的,從最初糾結用什麼壓測工具開始,到單鍊路壓測、中間件壓測,以及存儲系統壓測等一步步摸索,并借鑒其他友商的經驗和方案,直至現在,我們才最終在黑暗中摸索出了一條屬于我們自己的全鍊路壓測之路。2017

年的“雙11”前夕,整個研發、運維團隊處于緊急戰備狀态,從9月份開始,我們利用自研的“軍演系統”Titan總共發起了超過10次線上全鍊路壓測,除探測出系統的真實容量水位外,還挖掘出業務系統的性能瓶頸近 30處,成功做到了有指導地在大促前進行容量規劃和性能優化,讓系統堅如磐石。當使用者規模較小時,開發和測試同學随便線上下環境做一把功能測試,隻需要確定系統具備可靠性(檢驗系統是否能夠無差錯地執行預期的操作)即可,但随着使用者規模的線性上升,流量會越來越大,這時再光依靠正常的功能測試已無法滿足,流量上來了,就必須重視系統性能了,畢竟誰也不希望自己的系統被流量無情擊垮而導緻低可用性。

是以到了這個階段,大多數企業都會選擇線上下對各個子系統、中間件、存儲系統實施壓測,明确其吞吐量,但是因差異性問題,這樣的壓測結果資料,與線上還是有較大差距的,畢竟絕大多數企業的壓測環境并不會按照線上環境的機器數量1:1擴容部署,是以線下環境的壓測結果資料基本上僅供參考,并不能夠作為線上環境的指導資料,隻有直接線上上環境實施壓測才是唯一的明道。這裡為大家分享一下早先筆者所經曆的一次真實線上事故,某次大促備戰前夕,由基礎架構團隊牽頭給出系統所有核心鍊路的限流門檻值,但是負責線下壓測的相關同學,由于沒有仔細核對線上環境和線下環境訂單服務的 MySQL 資料源配置(線上環境maxWait參數設定不合理),且過于樂觀地評估出訂單服務的容量水位,可想而知,給出的限流門檻值必然會帶來災難性後果;果不其然,活動開始後沒多久,監控系統開始頻繁告警,DBA 首先按捺不住了,從監控系統中明顯可以發現某些訂單子庫的連接配接資源幾乎消耗殆盡,而訂單服務中擷取不到連接配接資源的線程長時間“hang”住,部分訂單服務完全癱瘓,上下遊逐層影響,最終産生雪崩,導緻部分使用者無法順利完成交易。正是吸取了這次事故的慘痛教訓,更加堅定了我們要線上上環境實施全鍊路壓測的決心。

直接線上上環境實施壓測是一件非常危險和困難的事情,決不能出現一絲失誤。大多數情況下,我們的業務系統都是有使用者在正常進行通路的,尤其是高峰期時絕不能因為壓測流量導緻系統故障進而影響使用者下單,更不能夠污染線上資料。試想一下,某個使用者的訂單資訊中,突然多出來10台iPhone X,你是送還是不送?或者餘額突然變少了,都是使用者絕對不能夠容忍的,并且線上環境往往還會伴随着各種定時任務,統計的時候如果把壓測資料也計算進收益中,營運部門的老大估計會請研發同學喝茶。

盡管困難重重,但是要探測出線上系統的真實容量水位,隻有此路通羅馬。是以系統需要做到能夠智能化到準确無誤地區分出哪些資料是真實使用者流量,哪些是壓測流量,筆者會在後續小節中為大家重點介紹線上實施全鍊路壓測的 4 個關鍵核心點:

● 業務系統、中間件如何配合改造更新;

● 如何将壓測資料引流到隔離環境中;

● 壓測資料如何構造;

● 超大規模的壓測流量如何發起。

那麼究竟什麼才是全鍊路壓測呢?在筆者回答這個問題之前,大家首先需要明确一點:系統中任何一個接口都不會獨立存在,假設A接口可以壓測出1w/s的QPS,那麼當A接口和B接口同時施壓時,A接口的QPS勢必會下降,原因其實很簡單,因為受限于一些共享資源;簡單來說,全鍊路壓測其實指的就是在特定的業務場景下,将相關的鍊路完整地串聯起來同時施壓,盡可能模拟出真實的使用者行為,當系統整站流量都被打上來的時候,必定會暴露出性能瓶頸,才能夠探測出系統整體的真實容量水位,以及有指導地在大促前進行容量規劃和性能優化,這便是線上實施全鍊路壓測的真正目的。

1.2 業務系統如何區分壓測流量

在為大家介紹業務系統如何區分壓測流量之前,我們首先來談論一個研發同學都比較關注和敏感的話題,業務系統是否需要配合進行相應的改造更新,明确告訴大家,一定程度上會,因為對于線上所有的寫接口來說,基本上是沒有辦法直接進行壓測的,并且全鍊路壓測任務并不會在業務初期就推動,一般都會選擇在業務中後期才實施,尤其是當業務越來越複雜的時候,改造的難度和成本就會越大。但是企業的基礎架構團隊應該意識到,絕大多數的改造工作都應該是在中間件、元件中完成,盡量避免對業務系統産生較大侵入,應該盡可能為研發同學提供便捷,讓其更專注于自身業務邏輯。我們在實施全鍊路壓測改造的時候,通過對業務進行逐一梳理,發現涉及的業務改造點居然達上百個之多,基本上業務系統的核心鍊路全部都需要配套進行改造。從最初的方案探讨到改造完成,基礎架構團隊基本上投入了全部的兵力,且涉及相關業務改造的研發同學更是不勝枚舉,總共花費了接近半年的時間(畢竟研發同學不可能完全專注于壓測改造,每天還需要處理線上問題,以及忙于實作各種應接

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

圖2-1 線上全鍊路壓測總體設計

不暇的業務需求),才最終完成了對相應業務系統、中間件,以及元件的改造更新任務。

1.2.1 壓測流量打标方案

線上業務系統如果想要準确區分出真實使用者流量和壓測流量,那麼就必然需要對壓測資料進行特殊标記,并且這個壓測标記還要能夠順利在一次請求涉及的所有後端服務調用的上下文中進行傳遞,當最終資料落盤或者調用第三方接口的時候,才能夠做到不影響和污染線上資料,如圖2-1所示。

對壓測資料進行打标的方式有許多種,本書筆者列舉了 2 種最常見的方式,如下所示:

● 在URL上進行打标;

● 在HTTP的header中進行打标。

假設在URL上進行打标,如下所示:

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

當在URL上添加打标參數(st=true)并向後端業務系統成功發起請求後,如果業務系統檢測到請求中已包含壓測标記,那麼就會把壓測标記在一次請求的整個生命周期中一直流轉下去。除可以選擇在 URL 上進行流量打标外,在 HTTP 請求的header中打标似乎也是一個不錯的選擇。當然,具體選擇哪一種流量打标方式,大家還需要結合自身業務場景而定。

1.2.2 在鍊路上下文資訊中傳遞壓測标記

在上一個小節中,筆者為大家介紹了如何對壓測流量進行打标,以便有判斷依據能夠讓業務系統區分出哪些是真實使用者流量,哪些是我們的壓測流量,當真正線上上進行壓測時才不至于把壓測流量誤當做正常流量進而污染線上資料。對壓測流量進行打标的方式非常簡單,無論是直接在URL上進行打标,還是選擇在header中進行打标都是可行的,判斷一次請求是否是壓測流量則需要在接入層就開始處理,如果檢測為壓測流量,當調用下遊服務時,就需要能夠順利把壓測标記在一次請求的整個生命周期中一直流轉下去。

大家思考下,流量區分和壓測标記傳遞等任務應該如何在業務系統中實施配套改造更新呢?或許有的同學認為這并非是一件難事,隻需要在業務代碼中稍微調整下,加上幾個條件判斷語句即可。盡管這種方式理論上可行,但是幾乎沒有任何一家網際網路企業會選擇采用這種方式來适配全鍊路壓測改造,抛開成本問題不談,最棘手的問題就是連負責相關業務的研發同學都沒有完全的把握能夠確定所改造的代碼邏輯不存在任何遺漏,要知道核心鍊路所牽涉的業務改造點可謂多不勝數,一旦壓測标記在向下傳遞的過程中出現了中斷,這将會導緻非常嚴重的後果,整個研發團隊都難辭其咎。

筆者之前曾經說過,對于線上所有的寫接口來說,基本上是沒有辦法做到直接進行壓測的,是以實施全鍊路壓測,業務系統必然需要配合相應的改造更新,但這并不代表需要業務系統經曆“傷筋動骨”的改造方式,既然此路不通,那麼還有什麼更好的辦法嗎?為了避免高侵入性問題所帶來的困擾,業界通常采用的做法是直接在中間件、元件中動手腳,将流量區分和壓測标記傳遞的任務交由具體的中間件、元件來負責,業務系統中唯一需要配合改動的就是對所依賴的相關中間件、元件版本進行更新即可。

既然是通過改造更新中間件、元件來處理流量區分和壓測标記傳遞等任務,那麼究竟應該改造哪些具體的中間件會比較适合呢?既然一次請求中涉及的所有後端服務調用都能夠被完整地串聯起來,那麼在分布式調用跟蹤系統中進行相應的全鍊路壓測改造更新就顯得順理成章。

簡單來說,我們采用的做法是,當對業務系統發起一次HTTP請求調用時,嵌套在分布式調用跟蹤系統中負責流量區分的攔截器會優先對請求進行攔截,然後嘗試從URL或者HTTP的header中擷取出壓測标記,如果确認為壓測流量,就将壓測标記放進目前線程的ThreadLocal中,待調用下遊服務時,再從中擷取出壓測标記并放入Dubbo的RpcInvocation中,逐層向下傳遞即可。全鍊路壓測改造任務不可能一帆風順,業務代碼中存在的一些不确定性因素很有可能會在改造過程中随時向你投遞一些“彩蛋”。我們在一條核心鍊路改造完成的一次聯調過程中發現壓測标記向下傳遞的過程中産生了中斷,經過排查後發現,業務代碼中存在通過直接建立線程的方式異步發起RPC請求,這樣一來,子線程便無法擷取到父線程設定在ThreadLocal中的壓測标記等資訊。

在此大家需要注意,程式中如果直接使用 new Thread()的方式建立線程并發起異步 RPC 請求,應該使用ThreadLocal 的派生類 InheritableThreadLocal,如果采用線程池的方式,那麼可以使用阿裡的TransmittableThreadLocal 來替代JDK原生的ThreadLocal,并設定相關環境變量,如下所示:

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

1.2.3 外部第三方接口走Mock

諸如短信、物流,以及支付等一些外部第三方接口,實際上并不在壓測範圍之内,如果我們不對這些外部接口進行統一的梳理和屏蔽,那麼線上上實際的壓測過程中,将會産生一些不必要的影響。以短信接口為例,這種按量付費的外部接口,完全沒有必要對其下血本進行“狂轟亂炸”,而且我們大部分時間根本不會關心這些短信内容。本書中筆者所提及的外部接口調用屏蔽方式,其實指的就是将壓測流量引流到Mock服務上,避免直接與外部第三方接口産生實際互動。

先來說一下我們最初的做法。當業務系統需要調用外部接口時,嵌套在分布式調用跟蹤系統中的 MockFilter 會對其進行攔截,如果檢測為壓測流量,則比對目标接口是否是外部接口,比對規則可以直接在配置中心内添加黑名單設定,如果滿足比對,就直接調用Mock服

務,Mock的具體傳回結果同樣也可以在配置中心内設定,如果壓測流量較大,運維同學仍然需要擴容較多的Mock服務來支撐壓測請求,由此可見 Mock 服務的運維成本相對還是相對較高的,是以我們不得不對此方案進行改進,不再單獨部署相關的Mock服務,而是直接将Mock 邏輯封裝在MockFilter内,除可以避免網絡損耗提升壓測品質外,更重要的是,有效控制住了成本開銷。如圖2-2所示。

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

圖2-2 Mock調用流程設計

1.2.4 壓測資料的隔離方案

之前筆者曾經提及,直接線上上環境實施寫壓測是一件非常危險和困難的事情,除會對目前正在通路系統的使用者産生影響外,還可能存在污染線上資料的風險。前者可以通過低峰期解決,也就是選擇在一個對使用者影響較小的時間區間内進行,而後者則成為擺在架構師面前的難題,同時也是業務系統配合改造更新的重點和難點。

我們當初在設計壓測資料的隔離方案時,考慮了實體隔離和邏輯隔離2種方案,前者的優點很明顯,但缺點就是增加了運維成本,加重了企業的負擔。我們線上存儲系統的規模是比較龐大的,如果全部都按照1:1的方式擴容出一套影子庫出來,這幾乎不現實,而且在非壓

測時段這些擴容出來的資源純粹就是一種浪費。是以,出于我們自身的業務特點,以及成本問題等多方面的綜合因素考慮,最終選擇了采用邏輯隔離方案來解決線上資料污染問題。

對于那些真正需要落盤的資料,以MySQL為例,我們選擇了在同一套生産庫執行個體下建立一個影子庫來存儲壓測資料,避免定時任務在統計的時候把壓測資料也計算其中。而對于那些中間資料,比如寫入Red is、消息隊列中的每一條壓測資料,都會統一加上特定的壓測辨別,并設定較短的存活時間,讓其自動失效。在此大家需要注意,由于壓測流量請求的是線上存儲系統,是以底層連接配接資源的占用、釋放等問題需要重點關注,千萬不能在壓測已經結束了,仍然還影響正常的使用者通路。在解決這類問題時,我們的思路是,服務啟動時避免觸發資料源的“init-method”屬性,當真正執行壓測時再建立會話連接配接,而且“minEvictableIdleTimeMillis”、“timeBetweenEvictionRunsMi llis”,以及“minIdle”等屬性也需要合理設定,最終要保證的就是快速釋放壓測資源所占用的線上資源。

大家思考下,DAL 層應該如何将壓測資料正确路由到影子庫上?一般而言,這一塊的改造工作最好是優先選擇在資料庫的Proxy層上進行,通過改造分庫分表中間件來解決路由問題。其次,大家還可以通過擴充Spring的AbstractRoutingDataSource類來實作一個特定的動态資料源,并重寫其determineCurrentLookupKey()方法,在該方法中嵌入路由邏輯,如果檢測為壓測資料,就傳回影子庫的資料源,反之就傳回線上資料源。

1.3 如何發起大規模的壓測流量

在前面幾個小節中,筆者為大家介紹了什麼是全鍊路壓測,以及為什麼需要線上上環境實施全鍊路壓測,并着重介紹了業務系統及相應的中間件、元件應該如何改造更新來适配全鍊路寫接口壓測。那麼接下來,我們再來看看如何模拟出超大規模的壓測流量來對線上系統實施全鍊路壓測。

在單鍊路壓測場景下,可選擇的壓測工具可謂是不勝枚舉,比如:Apache JMeter、Apache AB,以及Gatling等都是開發、測試同學非常熟悉和常用的。但這類壓測工具實際上都是通過單機部署,使用多線程或多程序方式模拟出并發使用者數來進行施壓的,以Apache AB為例,瞬間能夠發起的壓測流量實在有限,根本無法模拟出貼近真實線上環境的峰值流量。

實際上,筆者所在企業在最初的時候,全鍊路壓測的構思還并不成熟,隻是希望能有一種壓測工具能夠支援叢集打量,是以後來我們也調研過nGrinder,相比較而言,nGrinder确實可以在一定程度上滿足分布式壓測需求,支援部署多Agent的方式提升壓測流量,但是介于它的Controller存在瓶頸,能夠管理的Agent數量實在有限,以及對場景化需求的支援過于薄弱,是以我們最終決定開始自研适用于我們自身業務場景的全鍊路壓測軍演系統Titan。

1.3.1 資料構造平台

毋庸置疑,壓測資料可以說是整個全鍊路壓測體系中的核心,這關系到影子庫中的測試資料應該如何構造,以及下發給壓測引擎的請求參數檔案應該如何組裝。早期筆者在研發Titan時,并沒有建構資料構造平台(即資料工廠),每次壓測摸底前夕,測試同學幾乎都是以純手工的方式來組裝目标場景所需的一系列壓測參數,再儲存在檔案中的。顯而易見,這樣的效率非常低下,不僅需要花費大量的時間成本和人力成本,最悲劇的還是某些特殊參數還未使用卻失效過期,一旦出現這樣的情況,又需要花費測試同學大量的時間和精力去重新組裝,着實令人頭痛。依稀記得在某次大促壓測前夕,我們有幾十個待壓場景,預計是在淩晨零點開始施壓,結果從下午的5點開始,直至半夜11點壓測參數都還未完全組裝完成,其痛苦程度不亞于抄送一遍奧斯特洛夫斯基的《鋼鐵是怎樣煉成的》;

除需要手工組裝壓測參數外,影子庫中的測試資料(比如:測試店鋪、測試商品等)也同樣需要手動一條條刷進去。在經曆了那段苦不堪言且不願回首的石器時代,我們終于在2018年的“雙11”備戰期間實作了“四個現代化”,走上自動化道路,資料構

造平台孕育而生,如圖2-3所示。

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

圖2-3 資料構造平台設計

資料構造平台的3個核心任務:

● Dump線上資料,經曆脫敏、修正等階段後導入資料池;

● 負責将測試資料落盤影子庫;

● 根據目标場景導出相應的請求參數檔案。

我們的壓測資料來源是直接Dump的線上庫、Nginx等資料源,在把這些真實使用者資料導入資料池之前,會先把這些資料中包含的一些敏感資料(比如:電話、位址等)進行脫敏、修正,最後才會把這些加工後的資料導入資料池中以供備用。當需要執行壓測時,再根據具體的目标場景,将測試資料刷進影子庫,以及下發給執行引擎所需的壓測參數檔案。

1.3.2 自研全鍊路壓測軍演系統的一些經驗分享

如果現有的技術或架構不能有效滿足業務需要,才需要從“拿來主義”的消費者角色轉變為自行研發的生産者角色。畢竟在融合了高度開放、分享的網際網路當下,真正需要我們從零開始自研的架構或中間件真的不多了,因為當下你能夠遇見的問題,别人早已經曆過且提供相應的解決方案,是以在非必要的情況下,将時間投入業務系統的重構上,不斷減少系統的“熵”似乎更有意義;反之放手去做,但務必牢記,一定不能脫離業務。據筆者了解,餓了麼技術團隊的全鍊路壓測體系中,壓測引擎并非是自研的,而是使用的JMeter叢集。總之,隻要能夠滿足業務需要,選擇往往就是正确的。

如圖2-4所示,

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

圖2-4 Titan 2.x整體架構

Titan的整體架構主要由5部分構成,Manager作為管理控制台,主要負責鍊路和場景的管理;TaskService 負責壓測任務的編排,以及壓測流量的下發;Agent作為施壓節點,其任務就是對業務系統實施壓測;Detector作為水位檢測器,用于采集相關業務系統的監控名額資料,以及RT和業務失敗率,以便在壓測流量達到臨界水位時自動幹預壓測流量的下發;DataCollect 用于收集各個 Agent 節點的壓測資料合并上報。壓測編排和任務下發都是由TaskService負責,由于筆者所在企業使用的RPC架構為Dubbo,是以TaskService和Agent之間的通信也是基于Dubbo的RPC調用。

假設我們需要對某個目标場景實施壓測,TaskSer vice首先會執行任務編排(比如:任務ID配置設定、任務内容配置設定,以及空閑Agent排程等);待任務編排結束後,TaskService會更改目标Age nt所在注冊中心内的目前狀态資訊,當Agent感覺變化後,會主動向Ta skService 拉取任務,TaskService 節點越多,壓測前的預熱工作就會處理得越快。壓測參數的下發則是由資料構造平台來負責,由于資料構造平台在上一小節筆者已經為大家詳細介紹過了,是以就不再繼續闡述了。

壓測引擎或許是大家最關心的一個話題。Titan的壓測引擎并沒有什麼特别之處,針對HTTP接口,我們最初采用的是Apache HttpCompon ents包下的同步HttpClient,基于多線程模拟并發使用者數的方式來對線上業務系統施壓,這一點和JMeter、Apache AB等正常壓測工具的做法類似。但存在一個問題:假設總并發使用者數被設定為10W,當下遊接口的處理速度較快時,接入層每秒接收的請求數會遠高于此。我們在實際的壓測過程中發現,并發使用者數雖然隻有10W,但壓測時,峰值QPS達到了近100w/s,影響了我們對流量的評估。是以,在重構Titan 2.x版本時,我們選擇了采用Java11的異步HttpClient來發起HTTP請求,不再采用多線程模拟多并發使用者的方式發起流量,并在 Agent 端做好了相應的流量管控,抛開上/下行帶寬等因素,可以做到期望流量與實際流量基本持平。

在此我簡單對Java 11提供的HttpClient的基本使用做一個介紹。HttpClient的使用非常簡單,除支援同步和異步兩種程式設計模型外,還支援HTTP/2協定,甚至開發人員還能夠以Reactive Stream的方式來處理請求/響應的主體。HttpClient的使用示例,如下所示:

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

當壓測流量超出系統安全水位時,監控系統一定是紅燈常亮,告警短信、郵件不斷,為了避免線上業務系統發生雪崩,運維同學往往會要求流量達到臨界水位時停止繼續施壓,但通過觀察監控來手動停止壓測流量的下發往往存在一定的滞後性,這就好比載貨行駛的大貨車,突然急刹車往往也會因為慣性作用而導緻車輛繼續滑行很長一段時間。如圖 2-5 所示,為了確定線上系統不會被壓測流量擊垮,我們将Titan 和立體監控進行了關聯,并加入了水位檢測器,一旦壓測流

百萬級高并發網站架構設計之雙11大促備戰—全鍊路壓測

圖2-5 安全水位檢測機制

量超出線上業務系統的安全水位時,便會迅速自動幹預壓測流量的下

發。

早在2017年的上半年,筆者曾嘗試在GitHub上開源過Titan的1.x 版本,實際上,當時的版本還并不完善(比如:管理界面醜陋、壓測引擎不穩定,統計結果不準确等問題),在吸取了社群諸多好的建議後,我們的架構團隊開始大刀闊斧地對Titan進行重構更新,使之簡單易用、穩定高效。目前,Titan 2.x版本已經脫胎換骨,整個平台都已經越來越完善,關于新版本的Titan在後續将會有開源計劃。

1.4 本章小結

本章筆者着重為大家介紹了企業為什麼需要實施全鍊路壓測,以及在實施全鍊路壓測過程中業務系統、中間件,以及相應的元件應該如何配套改造更新,如何有效避免壓測流量污染線上資料。在本章的最後,筆者還為大家分享了自研軍演系統的一些經驗,希望大家能有所裨益。

繼續閱讀