應(yīng)用性能提升 70%,探究 mPaaS 全鏈路壓測的實現(xiàn)原理和實施路徑
業(yè)務(wù)背景
隨著移動開發(fā)行業(yè)的步入存量時代,App 整體架構(gòu)的負載能力、以及各個環(huán)節(jié)的優(yōu)化逐步成為各個開發(fā)者們關(guān)注的重點。
壓力測試就是實現(xiàn)以上功能的主要方案。一般可以基于壓力測試:
測試后端業(yè)務(wù)的負荷瓶頸;
評估整體架構(gòu)性能;
業(yè)務(wù)穩(wěn)定峰值;
排查出各節(jié)點的薄弱關(guān)系;
優(yōu)化系統(tǒng)資源;
避免短板效應(yīng);
為運營提供準確的用戶承載量作為作證,避免活動/新應(yīng)用的上線帶來的突發(fā)流量造成的用戶體驗不佳。
今天,我們將為大家介紹全鏈路壓測方案的是實現(xiàn)原理和實施路徑。
全鏈路壓測與原理
通常我們可以簡單的把負載性能=單機性能*機器總量這一公式套用到預(yù)估的方案中,但是在實際的場景下,常常會涉及到大量的業(yè)務(wù)節(jié)點,如DNS,網(wǎng)關(guān),數(shù)據(jù)庫等環(huán)節(jié),都有可能是導致整體業(yè)務(wù)性能的瓶頸,因而實際服務(wù)能力可能與預(yù)期存在較大誤差。
一般用戶會通過 loadrunner 等方案實現(xiàn)生產(chǎn)環(huán)境下的服務(wù)器性能壓力測試,但是在 mPaaS 應(yīng)用中,復(fù)雜的部署無法通過 MGS 網(wǎng)關(guān),高昂的費用等難點應(yīng)運而生,為了解決這些痛點。
mPaaS 團隊這邊依據(jù)多位客戶的述求,提供出 MGS 全鏈路壓測方案。
區(qū)別于以往的測試方案,全鏈路壓測方案中最大的不同是視角上的不同,站在客戶端角度上作為切入點,將整個服務(wù)端鏈路作為一個黑盒,以真實的 request 和 response 作為評估的依據(jù),模擬真實的業(yè)務(wù)請求,真實的數(shù)據(jù)流量,真實的用戶習慣,來達到得出盡可能真實的評估結(jié)果。
鏈路梳理
在一個標準的數(shù)據(jù)鏈路中,一般為以下模型
而在全鏈路壓測中,我們把整體的服務(wù)端實現(xiàn)視為一個黑盒,因而我們所需關(guān)注的焦點聚焦在前半段,重點可以概括為:
1.客戶端請求構(gòu)建;
2.客戶端請求發(fā)送并通過 MGS 網(wǎng)關(guān);
3.客戶端解析 MGS 網(wǎng)關(guān)返回的 response 并做出正確處理;
4.實現(xiàn)高并發(fā)的客戶端請求集群。
以上再次梳理,可以歸納出以下難點
難點1 客戶端請求構(gòu)建
mPaaS 移動網(wǎng)關(guān) RPC 通訊是在 HTTP 協(xié)議基礎(chǔ)之上的實現(xiàn)的一種標準化接口方式,在復(fù)用 HTTP 請求標準的前提下,定義了一套數(shù)據(jù)交換格式,采用Header,Body 作為實際區(qū)分,可以近似理解為,通過Header 中的Operation-Type做為真實api指向,將body部分依據(jù)規(guī)則封裝后進行轉(zhuǎn)發(fā)。
在該步驟中,我們以 JMeter 作為實現(xiàn)方案,Jmeter 靈活的腳本特性可以良好的實現(xiàn)客戶端的真實請求模擬。
難點2 數(shù)據(jù)加解密
mPaaS 移動網(wǎng)關(guān) RPC 請求特有的數(shù)據(jù)加密方式構(gòu)建請求中比較復(fù)雜的部分??蛻魝?cè)已有的測試方案不能覆蓋這部分能力,因此往往選擇關(guān)閉網(wǎng)關(guān)服務(wù)端驗簽和加密功能實施壓測。
這種方式的隱患在于無法估計加解密給網(wǎng)關(guān)服務(wù)器帶來的計算壓力。
根據(jù)經(jīng)驗,不同的加解密算法配置,對網(wǎng)關(guān)的吞吐量有 20% ~ 40% 影響。在此階段,由金融線 SRE 團隊基于用戶生產(chǎn)環(huán)境定制開發(fā)的 JMeter 插件 MGSJMeterExt,該插件逆向?qū)崿F(xiàn)了請求體的加密和解密過程,使得壓測腳本的編排可以包括加密部分。
難點3 請求簽名構(gòu)建
mPaaS 移動網(wǎng)關(guān) RPC 請求特有的簽名校驗機制也比較特殊。同數(shù)據(jù)加解密一樣,目前客戶側(cè)無方案可覆蓋這部分能力,往往選擇關(guān)閉接口驗簽進行測試。同樣借助 MGSJMeterExt,可以實現(xiàn)在 JMeter 中實現(xiàn)對報文的正確簽名,并通過服務(wù)端校驗。
難點4 壓測集群環(huán)境部署
對于壓測來說,需要的重點側(cè)重于真實,真實的流量入口,真實的并發(fā)數(shù)量,才能得出真實的結(jié)果,而自行實現(xiàn)壓測環(huán)境,高昂的集群部署費用,也成了不必要的開支.
因而我們推薦用戶采用阿里云 PTS 作為壓測平臺,基于其他方案,具有部署簡易,支持 Jmeter 腳本,流量真實等優(yōu)勢,也可為用戶提供更為詳實的壓測報告。
概覽
以上模型簡單可以歸納為以下結(jié)構(gòu)
全鏈路方案及實施
Part1 前期準備及調(diào)研
在前期階段,目標是為了為實際的壓測提供相關(guān)的準備和數(shù)據(jù)支撐,確立壓測目標和整體方向。
1.1 目標及數(shù)據(jù)準備
1.客戶需要明確自身的壓測目標和壓測目的,基于壓測目標,參照以往的運營數(shù)據(jù),給出涉及到的具體業(yè)務(wù)類目和可能的用戶行為習慣,在整體的業(yè)務(wù)中各習慣所帶來的相關(guān)比重關(guān)系。
1.2 客戶端準備
1.客戶端這邊需要依據(jù)相應(yīng)的業(yè)務(wù)目標,整理出在客戶端實現(xiàn)中可能涉及到的接口和數(shù)據(jù)流程,如是否包含前置步驟,如登陸等,是否包含強制的步驟,如首頁的刷新等,通過抓包等收集該步驟中真實的 request 和 response,以及確定符合預(yù)期的值條件。
2.該步驟涉及業(yè)務(wù)結(jié)構(gòu)的不同,亦可由服務(wù)端接口端完成該準備。
1.3 服務(wù)端準備
1.服務(wù)端這邊依據(jù)1.2中統(tǒng)計的相關(guān)接口,做好相關(guān)的數(shù)據(jù)擋板,避免導致測試數(shù)據(jù)污染真實數(shù)據(jù)庫。
2.由于在 mPaaS 全鏈路壓測中,服務(wù)端被視為黑盒,因而需要實現(xiàn)對于服務(wù)端各業(yè)務(wù)的性能指標的監(jiān)控,為后期的服務(wù)端調(diào)優(yōu)作為依據(jù)。
1.4 MGSJMeterExt 插件準備
由于 MGSJMeterExt 需要依據(jù)實際網(wǎng)關(guān)環(huán)境進行定制開發(fā),需要用戶提供以下數(shù)據(jù):
1.工作空間相關(guān)環(huán)境數(shù)據(jù)
2.加密算法和公鑰
Q&A答疑
Q:如何實現(xiàn)壓測腳本?
A:會由我們的專家團隊和現(xiàn)場同學完成簡單場景下的壓測腳本培訓,在實際的場景下,可能涉及到業(yè)務(wù)的多個環(huán)節(jié),如登陸 token 的獲取,一些明確的前置步驟,這一類由于涉及到復(fù)雜的業(yè)務(wù)場景,需要客戶在阿里專家團隊的協(xié)助下自行完成。
Q:為什么是全鏈路的?
A:雖然我們的壓測腳本是基于客戶端邏輯實現(xiàn)的,但是我們實際上是模擬了真實的數(shù)據(jù)請求,也會確認服務(wù)端的返回是否達到預(yù)期,涉及到整個完整的數(shù)據(jù)鏈路及節(jié)點。
Q:鏈路的指標如何實現(xiàn)埋點?
A:壓測方案的對象是基于黑盒的,通過系統(tǒng)的 pts 指標,請求參數(shù)與返回的回報率,校驗符合預(yù)期結(jié)果的成功率,來確認基于用戶角度下的整個架構(gòu)所能負載的性能,對于一些后端的指標,由于不同的客戶采用的服務(wù)端的架構(gòu)存在不少的差異,對于后端這類指標,一般對應(yīng)的服務(wù)商都能提供相關(guān)的監(jiān)控方案,也無需 mPaaS 這邊進行處理。
Q:為什么使用 PTS?
A:mPaaS 團隊實際上提供的是 MGS 的通訊解決方案,協(xié)助客戶完成 PTS腳本的編寫,并不強制使用 PTS,只需要能提供相關(guān)的 Jmeter 集群部署環(huán)境即可,且 PTS 相關(guān)資源需要用戶自行采購,但目前 mPaaS 團隊基于多個案列評估,相對而言,使用 PTS,有更高的性價比,且能提供更為符合預(yù)期的壓測環(huán)境,完整的壓測報告,故推薦用戶使用 PTS 進行壓測。
Q:有沒有什么詳細的標準,如2c4g情況下,或者4c8g下,應(yīng)該達到怎樣的性能指標?
A:壓力測試本身即是為了明確在相關(guān)的系統(tǒng)資源下,可以達到的性能指標,由于服務(wù)端的架構(gòu)不同,實際業(yè)務(wù)涉及的流程節(jié)點不同,不同環(huán)境下的性能存在著巨大的差異,這些即是使用壓力測試的目的,需要通過壓測才能明確真實的指標和評估各個節(jié)點的實際資源耗時。
Part2 Jmeter開發(fā)與腳本改造
我們歸納出了 MGS 通訊方案的特殊側(cè)重點,因而我們需要在 Jmeter 完成這幾點的改造
2.1 Header 改造
在 Header 中,我們需要注意以下幾點:
1.MGS 網(wǎng)關(guān)協(xié)議是依賴于一些 Header 字段的,因而需要確保網(wǎng)關(guān)參數(shù)齊全。
2.部分參數(shù)為固定值,可直接寫死,相關(guān)的配置可以參考控制臺下載的配置文件。
3.如業(yè)務(wù)有其他的 Header 依賴如 cookide 等業(yè)務(wù)上需要使用,也可直接添加,MGS 網(wǎng)關(guān)不會對 Header 信息進行過濾。
2.2 Url改造
在 URL 中,我們需要注意以下幾點:
1.URL 的實際指向應(yīng)為 MGS 網(wǎng)關(guān),而非實際的業(yè)務(wù)服務(wù)器,相關(guān)的配置可以參考控制臺下載的配置文件。
2.目前所有到 MGS 網(wǎng)關(guān)的請求均為 post,如有 get 請求,也是由 MGS 進行轉(zhuǎn)發(fā)時變?yōu)?get 的,在與 MGS 的通訊中也為 post。
3.Body 部分如無特殊需求建議如圖所示即可。
2.3 Request改造
在 Request 中,我們需要注意以下幾點:
1.這里的加密/驗簽,依賴于 MGSJMeterExt 文件,需要引用該文件。
2.一般情況下僅需修改 //config 部分即可。
3.下述部分一般為統(tǒng)一方案,主要為了實現(xiàn)加密和驗簽,無需修改。
2.4 Response改造
在 Response 中,我們需要注意以下幾點:
1.在這里考慮到施壓機性能,不會影響到服務(wù)端的評估能力,因此若無數(shù)據(jù)二次使用需求,或結(jié)果判斷需求,這里可不寫
2.如有相關(guān)需求,可在這里完成 Response 回參的二次處理
Part3 實際壓測
大致的步驟可歸納為:
3.1 PTS 及腳本性能調(diào)優(yōu)
阿里云性能測試服務(wù)(PTS)提供了方便快捷的云端壓測能力,在本次壓測服務(wù)中,借助 PTS 實現(xiàn)互聯(lián)網(wǎng)壓力流量的輸入。
有意思的點在于,加解密計算不僅給網(wǎng)關(guān)帶來計算壓力,也會給施壓機帶來了一定的計算壓力。因此,第一個版本的插件和壓測腳本在實施前,我們首先進行了針對試壓機進行了的“壓力測試”。
第一輪基礎(chǔ)測試
PTS 試壓機配置:
1.PTS 單 IP 單元配置
2.并發(fā)數(shù) 500(單機最高并發(fā))
3.固定壓力值流量模型
4.兩分鐘壓測時常
從回收的壓測報告看,TPS 結(jié)果并不高,但返回 RT 值并不高:
接下來觀察施壓機的性能表現(xiàn),可以看到施壓機的 CPU 使用率水位一直比較高,因此有理由懷疑加密計算壓力給施壓機的壓力釋放帶來比較大的影響。
通過對重復(fù)內(nèi)容加密結(jié)果的緩存,大幅降低了計算壓力;同時,為了避免緩存設(shè)計引起內(nèi)存問題,對緩存上限進行了限制。
第二輪測試
與第一輪的測試配置完全相同,僅更換了優(yōu)化后的加密插件。從回收的測試報告看,場景 TPS 有 75% 的提升:
從施壓機 CPU 性能看有一個明顯的優(yōu)化。
第三輪測試
有了第一輪的摸底和第二輪的優(yōu)化情況,第三輪測試在配置上使用兩臺施壓機滿負荷進行壓測,觀察壓測結(jié)果:
從結(jié)果看,壓測腳本和編排過程符合預(yù)期,可以在客戶生產(chǎn)環(huán)境進行正式的 PTS 云端壓測。
3.2 生產(chǎn)環(huán)境壓測摸底
在正式壓力測試開始,進行了若干輪小規(guī)模的壓力測試,觀察后端系統(tǒng)的工作狀態(tài)是否符合預(yù)期。摸底期間發(fā)現(xiàn)如下問題:
問題一:Nginx流量轉(zhuǎn)發(fā)不均
從MGS容器的日志表現(xiàn)上看,部分容器始終獲取不到任何請求,經(jīng)過排查發(fā)現(xiàn)該問題由三個原因?qū)е拢?/p>
1)DMZ區(qū)Nginx轉(zhuǎn)發(fā)配置少配了一個MGS容器IP;
2)DMZ區(qū)到每一個MGS容器IP的網(wǎng)絡(luò)策略均需要開通訪問權(quán)限;
3)Nginx轉(zhuǎn)發(fā)規(guī)則設(shè)置為iphash,在單IP來源的測試情況,流量僅能轉(zhuǎn)發(fā)到一個容器上。
配置了正確的IP列表、開通了網(wǎng)絡(luò)權(quán)限以及修改轉(zhuǎn)發(fā)規(guī)則后,該問題得到解決。
問題二:特定 MGS 容器基礎(chǔ) CPU 負載過高
前期測試發(fā)現(xiàn),有一臺 MGS 容器(mpaasgw-7)在靜默狀態(tài)下的 CPU 負載在25%,不符合預(yù)期。
登錄容器發(fā)現(xiàn)存在一個 JPS 進程,消耗了大量的 CPU。懷疑是前期調(diào)測階段調(diào)用后未正常釋放。殺掉JPS進程后問題解決,為了避免其他問題,一并重啟了該容器
注:JPS, Java Virtual Machine Process Status Tool),是java提供的一個顯示當前所有java進程pid的命令,參見:https://docs.oracle.com/javase/7/docs/technotes/tools/share/jps.html )。
問題三:CoreWatch 監(jiān)控平臺無法訪問
CoreWatch 控制臺無法訪問,瀏覽器中報 502 錯誤。重啟 CoreWatch 容器后,頁面可以加載,但始終處于加載中狀態(tài)。
http://corewatch.*.com/xflush/env.js 一直處于pending狀態(tài)。排查發(fā)現(xiàn) ALB 實例監(jiān)聽配置存在錯誤,修正后問題得到解決。
3.3 生產(chǎn)環(huán)境壓力測試&總結(jié)
在解決了 3.2 中的所有問題后,系統(tǒng)具備了壓力測試的條件,正式壓測會針對“加密場景”和“非加密”場景分別做壓力測試。
由于生產(chǎn)數(shù)據(jù)不做外泄,以下僅對遇到的問題進行一些例舉。
“加密”情況下測試
1.壓測時發(fā)現(xiàn)在并發(fā)數(shù) 500 左右即出現(xiàn) TPS 不做增長,代表著可能到達了瓶頸。
2.觀察 MGS 網(wǎng)關(guān)容器的負載情況,整體 CPU 負載達到極限。
3.同一時間段的 MCUBE 容器 CPU 負載情況健康,其他性能指標(IO、網(wǎng)絡(luò)等)也處于健康狀態(tài)。
4.從上述情況看,加密場景下,主要性能瓶頸在 MGS 網(wǎng)關(guān)上,根據(jù)經(jīng)驗及流程分析,主要性能壓力由報文加解密過程中的密集計算所帶來。要解決這一瓶頸,需要對 MGS 容器進行擴容。
“不加密”情況下的測試
1.TPS 的增長在并發(fā)達到 1000 左右時停止增長。一般情況下,這種情況說明觸及了系統(tǒng)容量的瓶頸。
2.觀察 MGS 網(wǎng)關(guān)容器的負載情況,與加密情況下的情況不同,此時整體 CPU 負載均不高。
3.與此同時,根據(jù)網(wǎng)絡(luò)組的反饋:壓測期間互聯(lián)網(wǎng)到 DMZ 區(qū)的 TCP Session數(shù)量是 DMZ 區(qū)到內(nèi)網(wǎng)區(qū)的3~4倍,交易內(nèi)網(wǎng)段的防火墻 CPU 壓力較高。
4.結(jié)合上述三種表現(xiàn),懷疑觸及網(wǎng)絡(luò)層面瓶頸。根據(jù)現(xiàn)場情況發(fā)現(xiàn),DMZ 區(qū) Nginx 轉(zhuǎn)發(fā)到內(nèi)網(wǎng)時沒有采取長連接保持策略。修改Nginx配置,添加keepalive 1000配置,重新進行第二輪測試。
關(guān)于參數(shù)Keepalive說明:默認情況下,Nginx訪問后端都是用的短連接(HTTP1.0),每一個新的請求,Nginx 都會新開一個端口和后端建立連接,后端執(zhí)行完畢后主動關(guān)閉該鏈接。Keepalive參數(shù)會告知Nginx和后端服務(wù)器之間緩存的長連接數(shù)量,當新的請求進來時,可直接復(fù)用TCP連接,減少建立TCP連接所帶來的性能影響。參見:http://nginx.org/en/docs/http/ngx_http_upstream_module.html。
總結(jié)
在上述問題優(yōu)化后,非加密場景下至少有 70% 的性能提升,加密場景下 10%的性能提升,并在 MGS 擴容完成后可實現(xiàn)大幅的性能提升,調(diào)優(yōu)的結(jié)果遠超預(yù)期。