陳皓 張博民
摘? 要:隨著硬件性能的提升、網(wǎng)絡(luò)帶寬的增加和數(shù)據(jù)量的急劇增長,傳統(tǒng)的單機應(yīng)用已無法滿足現(xiàn)代企業(yè)的需求,取而代之的是基于分布式的軟件系統(tǒng)。這些軟件系統(tǒng)在提供強大計算能力的同時,也引入了復(fù)雜性。文章介紹一種新型的基于云原生架構(gòu)的生產(chǎn)線上全鏈路壓力測試方法——Shadow Service,通過實現(xiàn)業(yè)務(wù)一致性、數(shù)據(jù)一致性、資源一致性和各種隔離性,保證了測試結(jié)果的準(zhǔn)確性和生產(chǎn)系統(tǒng)的安全性。同時,詳細(xì)介紹了如何在一個簡化后的訂單支付場景中使用Shadow Service實現(xiàn)壓力測試。
關(guān)鍵詞:生產(chǎn)環(huán)境;壓力測試;影子服務(wù);服務(wù)網(wǎng)格;云原生
中圖分類號:TP311.5? 文獻標(biāo)識碼:A? 文章編號:2096-4706(2023)11-0069-04
An End-to-End Pressure Testing Technology for a Completely Invasive Production Line
CHEN Hao, ZHANG Bomin
(MegaEase Inc., Beijing? 100025, China)
Abstract: With the improvement of hardware performance, the big increment in network bandwidth, and the rapid growth of data volume, traditional stand-alone applications can no longer meet the needs of modern enterprises. Instead, distributed-based software systems have emerged. These software systems provide powerful computing capabilities while introducing complexity. This paper introduces a novel cloud-native architecture-based end-to-end pressure testing method for production lines—Shadow Service. By ensuring business consistency, data consistency, resource consistency, and various isolation levels, the accuracy of test results and the security of production systems are guaranteed. At the same time, it details how to use Shadow Service to achieve pressure testing in a simplified order payment scenario.
Keywords: production environment; pressure testing; shadow service; service grid; cloud native
0? 引? 言
在網(wǎng)絡(luò)時代,一個大型的互聯(lián)網(wǎng)應(yīng)用需要承受數(shù)以億計的訪問量,這需要我們對應(yīng)用中所有的服務(wù)進行全面完整的全鏈路壓力測試,但這面臨著巨大的挑戰(zhàn),傳統(tǒng)測試方法不僅成本高昂且無法保證準(zhǔn)確性,還需要巨大的工作量并存在破壞生產(chǎn)系統(tǒng)的風(fēng)險。為了應(yīng)對這些問題,MegaEase提出了Shadow Service技術(shù),基于云原生的流量調(diào)度和Service Mesh技術(shù),實現(xiàn)了業(yè)務(wù)一致、數(shù)據(jù)一致、資源一致以及業(yè)務(wù)隔離、數(shù)據(jù)隔離、流量隔離和資源隔離。這種方法不需要修改任何代碼,成本低,能夠保證業(yè)務(wù)邏輯與生產(chǎn)環(huán)境的一致性,同時可以使用生產(chǎn)數(shù)據(jù)進行測試,保證測試結(jié)果的準(zhǔn)確性,且安全可靠。因此,Shadow Service成為網(wǎng)絡(luò)時代全站壓力測試的理想選擇。
1? 背景介紹
隨著硬件性能越來越強,帶寬越來越高,數(shù)據(jù)越來越多,傳統(tǒng)的單機應(yīng)用已經(jīng)無法滿足用戶需求,取而代之的是由各種組件基于網(wǎng)絡(luò)而構(gòu)成的軟件系統(tǒng)。
但這種軟件系統(tǒng),在帶來更強大的計算能力的同時,也引入了單機時代所不具有的復(fù)雜性。今天,一個完整的軟件系統(tǒng),模塊數(shù)量少則幾十,多則成千上萬。并且,為了提高開發(fā)上線速度,這些模塊會由不同的團隊使用不同的語言開發(fā),這也讓模塊間的通信變得更加復(fù)雜。
同時,今天的業(yè)務(wù)模式相比過去也發(fā)生了很大的變化,類似雙十一的促銷活動,會讓系統(tǒng)承受數(shù)倍、數(shù)十倍于日常的壓力。所以,壓力測試變得日益重要,但傳統(tǒng)的測試方法也變得越來越無法適應(yīng)業(yè)務(wù)需求。
2? 問題和難點
2.1? 專用測試環(huán)境的問題
在單機時代,使用“1:1”的測試環(huán)境,是非常好的壓力測試方法。但到了網(wǎng)絡(luò)時代,這種做法卻可能非常不切實際。
1)成本問題。要測試單機軟件,即使是獨立開發(fā)者,絕大多數(shù)情況下也可以輕松地購買一臺獨立的測試用計算機;但今天的系統(tǒng)所需的資源太多了,要想1:1的按照生產(chǎn)系統(tǒng)搭建一套測試系統(tǒng),單是服務(wù)器成本就會高的讓大多數(shù)公司難以承受,更不用說還可能有帶寬、電力、機房等費用。
2)環(huán)境問題。即使我們在成本上沒有問題,但是真的“1:1”建起測試環(huán)境,保持這個測試環(huán)境與生產(chǎn)環(huán)境的軟件、數(shù)據(jù)完全一致也充滿挑戰(zhàn)。在實際工作中,測試環(huán)境與生產(chǎn)環(huán)境的差異會隨著時間的推移越來越大,最終導(dǎo)致測試結(jié)果失真。
3)數(shù)據(jù)問題。我們還會面對測試數(shù)據(jù)的問題,如果不能保證測試環(huán)境的數(shù)據(jù)與生產(chǎn)環(huán)境接近甚至相同,測試結(jié)果就不可信。比如一個類似微博的系統(tǒng),像作者這種普通用戶一般只有幾十或幾百人關(guān)注,所以我發(fā)一條消息,隨便怎么做都可以很容易地通知所有關(guān)注者。但對一個千萬大V,情況就會截然不同。所以,我們不能簡單地使用模擬數(shù)據(jù)進行測試。
4)安全問題。為了讓測試結(jié)果真實可靠,最好能夠把完整的生產(chǎn)數(shù)據(jù)導(dǎo)入到測試環(huán)境。乍看上去,這只需要簡單地備份恢復(fù)下數(shù)據(jù)庫,但生產(chǎn)環(huán)境包含大量敏感數(shù)據(jù),隨意復(fù)制到測試環(huán)境無疑會極大地增加數(shù)據(jù)泄露的風(fēng)險。
2.2? 在生產(chǎn)環(huán)境進行測試的問題
因為使用測試環(huán)境進行壓測存在諸多困難,人們就把目光轉(zhuǎn)向了生產(chǎn)環(huán)境,嘗試直接利用生產(chǎn)環(huán)境上的壓力低谷時段,比如凌晨,進行測試。但這是一種侵入式的解決方案,涉及修改甚至重新定義業(yè)務(wù)邏輯,所以同樣面臨巨大挑戰(zhàn)。
假設(shè)我們要修改的是一個網(wǎng)購系統(tǒng),那么用戶購物下訂單的流程應(yīng)該會涉及用戶、訂單、支付等一系列的模塊。
1)如果我們要修改用戶模塊,那么我們需要用代碼判斷過來的請求是應(yīng)該走測試邏輯還是生產(chǎn)邏輯。比較常見的方法是預(yù)先指定一個用戶ID的范圍,如果是這個范圍的用戶,就走測試邏輯,否則走生產(chǎn)邏輯。
2)用戶模塊之后,邏輯走到了訂單模塊,這時,我們可能仍然希望通過用戶ID來判斷是否應(yīng)該走測試邏輯,但實際情況卻可能是:經(jīng)過一系列的復(fù)雜處理流程,訂單模塊根本看不到用戶信息,所以此路不通。
3)為了讓訂單模塊能區(qū)分出正常訂單和測試訂單,就必須在用戶模塊增加一些處理邏輯,比如給訂單號加上特殊標(biāo)記等。但是,在一個復(fù)雜的系統(tǒng)里,用戶模塊并不容易知道后續(xù)流程要經(jīng)過的所有模塊,所以,為了不影響正常的生產(chǎn)邏輯,僅僅保證測試狀態(tài)的正常傳遞就需要付出不小的努力,更不用說還要考慮是否要訪問不同的數(shù)據(jù)集,是否要模擬第三方服務(wù)等各種情況。
很明顯,這種業(yè)務(wù)邏輯的修改,所需的工作量與功能點數(shù)量成正比。但除了巨大的工作量,更嚴(yán)重的問題是,在辛苦的修改之后,有誰能保證所有需要做的修改都改了,并且改對了?而萬一有遺漏或錯誤,就有可能破壞生產(chǎn)系統(tǒng),這個風(fēng)險實在是太大了,我們很難承受。
3? 解決之道
3.1? 一致性和隔離性
從前面的分析可以看出,傳統(tǒng)的測試方法或者成本高昂且得不到準(zhǔn)確的數(shù)據(jù),或者工作量巨大且存在破壞生產(chǎn)系統(tǒng)的風(fēng)險。因此,MegaEase認(rèn)為,要解決網(wǎng)絡(luò)時代的全站壓力測試問題,必須使用一種全新的方法,而這種方法的關(guān)鍵在于“三一致”和“四隔離”。
“三一致”是指業(yè)務(wù)一致、數(shù)據(jù)一致和資源一致。也就是說,測試系統(tǒng)和生產(chǎn)系統(tǒng)應(yīng)該完全相同,只有這樣,才能得到準(zhǔn)確的測試數(shù)據(jù)?,F(xiàn)實地說,100%的一致并不容易做到,比如,我們通常無法要求第三方配合我們進行測試,所以,只能使用模擬的方法替換掉部分第三方依賴。但我們?nèi)匀恍枰M最大可能保證兩個系統(tǒng)的一致性。
“四隔離”是指業(yè)務(wù)隔離、數(shù)據(jù)隔離、流量隔離和資源隔離。這些隔離,都是為了將生產(chǎn)系統(tǒng)和測試系統(tǒng)完全分開,避免它們相互影響。很顯然,三一致解決的是測試結(jié)果的準(zhǔn)確性問題,而四隔離則保證了測試過程不會影響生產(chǎn)系統(tǒng)。
基于上面的定義,我們可以使用一種叫Shadow Service的技術(shù),其主要利用云原生中的SideCar和Service Mesh技術(shù)。通過Shadow Service,我們可以非常容易地為系統(tǒng)中的所有的應(yīng)用服務(wù)創(chuàng)建一個影子(Shadow)副本,除了帶有Shadow標(biāo)記之外,這些影子副本與原始服務(wù)完全相同,從而保證了業(yè)務(wù)一致和業(yè)務(wù)隔離。同時,Shadow Service還會自動創(chuàng)建一條流量分配規(guī)則,將帶有特殊標(biāo)記的流量,比如,我們在用于測試的請求協(xié)議頭中加上一個標(biāo)志Request-Header: Test,通過Shadow Service的Mesh Ingress組件,將此請求作為測試請求轉(zhuǎn)發(fā)到服務(wù)副本,將其他沒有該標(biāo)識的請求發(fā)送給原始服務(wù),以實現(xiàn)流量隔離。
在數(shù)據(jù)方面,Shadow Service可以根據(jù)配置替換掉包括MySQL、Kafka、Redis等在內(nèi)的多種中間件的連接信息,并借此改變數(shù)據(jù)請求的發(fā)送目標(biāo),這保證了數(shù)據(jù)隔離。而用戶則可以直接將生產(chǎn)數(shù)據(jù)復(fù)制一份作為測試數(shù)據(jù)來保證數(shù)據(jù)一致。
資源一致和資源隔離是指測試系統(tǒng)要使用與生產(chǎn)系統(tǒng)規(guī)格相同的資源,但不應(yīng)該共享同一套資源。這主要是一個硬件問題,但Kubernetes已經(jīng)在軟件層面給出了非常好的答案,而Shadow Service是建立在Kubernetes之上,所以,通過將服務(wù)副本部署到新的Pod中,資源一致和資源隔離就都得到了保證。
3.2? Shadow Service工作方式
下面我們以一個簡化后的訂單支付的場景,介紹一下Shadow Service的具體使用方法。這個場景涉及訂單(Order)和支付(Payment)兩個服務(wù),訂單服務(wù)會調(diào)用支付服務(wù),支付服務(wù)最終會調(diào)用第三方服務(wù)(圖中未畫出)來完成支付,同時,訂單服務(wù)還會訪問MySQL數(shù)據(jù)庫。整個系統(tǒng),通過MegaEase的EaseMesh部署在Kubernetes中,部署過程中,EaseMesh會向應(yīng)用的Pod中注入的SideCar(基于Easegress)和JavaAgent(基于EaseAgent),從而劫持應(yīng)用發(fā)出的HTTP請求和數(shù)據(jù)請求,實現(xiàn)前面提到的“三一致”和“四隔離”。系統(tǒng)的總體架構(gòu)如圖1所示。
要對其進行測試,我們需要首先創(chuàng)建數(shù)據(jù)庫的副本。這一步,可以通過數(shù)據(jù)庫的備份恢復(fù)功能來完成,如圖2所示,因為數(shù)據(jù)副本和原始數(shù)據(jù)位于同一個安全域,所以不必對數(shù)據(jù)進行脫敏處理。
然后,使用下面的配置通過EaseMesh的命令創(chuàng)建訂單服務(wù)的shadow副本和灰度規(guī)則。注意,在創(chuàng)建服務(wù)的副本時,我們將其使用的數(shù)據(jù)庫指向了剛剛創(chuàng)建的數(shù)據(jù)庫副本。最終系統(tǒng)架構(gòu)如圖3所示。
kind: ShadowService
apiVersion: mesh.megaease.com/v1alpla1
metadata:
name: shadow-order-service
spec
serviceName: order-service
namespace: megaease-mall
mysql:
uris: "jdbc:mysql://172.20.2.216:3306/shadow_order_db..."
userName: "megaease"
password: "megaease"
最后,因為不想在測試的時候?qū)嶋H支付費用,我們要用下面的命令Mock支付服務(wù)。注意,調(diào)用第三方支付服務(wù)時通常會涉及多個非常復(fù)雜的安全驗證步驟,這導(dǎo)致這個服務(wù)難以被直接Mock。所以,我們把第三方服務(wù)包裝成了系統(tǒng)內(nèi)部的服務(wù),并借此簡化了調(diào)用接口,下面Mock的實際上是這個包裝后的服務(wù):
kind: Mock
apiVersion: mesh.megaease.com/v1alpha1
metadata:
name: payment-service
registerTenant: megaease-mall
spec:
enabled: false
rules:
- match:
pathPrefix: /
headers:
Request-Header:
exact: Test
code: 200
headers:
Content-Type: application/json
body: '{"result":"succeeded"}'
這樣就完成了整個測試系統(tǒng)的創(chuàng)建,我們可以向其發(fā)送帶有Request-Header: Test頭部的請求來進行壓力測試。最終的系統(tǒng)架構(gòu)如圖4所示。
3.3? Shadow Service的優(yōu)勢
相對于傳統(tǒng)的測試方法,使用Shadow Service進行壓力測試在以下5個方面具有明顯的優(yōu)勢:
1)0代碼修改:全部通過配置完整,不需要修改任何代碼,沒有改出Bug的風(fēng)險。
2)低成本:在使用云服務(wù)器的情況下,測試用的硬件資源隨用隨申請,用完就釋放,僅需要為實際使用時段付費。
3)業(yè)務(wù)邏輯與生產(chǎn)環(huán)境基本一致:除少數(shù)被Mock的服務(wù)外,測試系統(tǒng)與生產(chǎn)系統(tǒng)完全一致,最大程度避免了業(yè)務(wù)邏輯的差異導(dǎo)致的誤差。
4)可以使用生產(chǎn)數(shù)據(jù)進行測試:測試系統(tǒng)和生產(chǎn)系統(tǒng)的數(shù)據(jù)完全一致,保證了測試結(jié)果的準(zhǔn)確性。
5)安全:雖然測試時使用的是生產(chǎn)數(shù)據(jù),但測試系統(tǒng)和生產(chǎn)系統(tǒng)處于同一個安全域,所以沒有增加數(shù)據(jù)泄露風(fēng)險。
4? 結(jié)? 論
通過Service Mesh以及Shadow Service技術(shù)把生產(chǎn)環(huán)境的應(yīng)用服務(wù)和數(shù)據(jù)復(fù)制出一份用于測試,并通過流量網(wǎng)關(guān)進行測試流量的調(diào)度,我們可以在極低的成本下,實現(xiàn)業(yè)務(wù)一致、數(shù)據(jù)一致、資源一致以及業(yè)務(wù)隔離、數(shù)據(jù)隔離、流量隔離和資源隔離,同時,也避免了對代碼的修改,降低了成本,保證了業(yè)務(wù)邏輯與生產(chǎn)環(huán)境的一致性,并可以使用生產(chǎn)數(shù)據(jù)進行測試,確保了測試結(jié)果的準(zhǔn)確性和系統(tǒng)安全。因為只需要在付出一定的低成本云計算基礎(chǔ)硬件資源,Shadow Service成為網(wǎng)絡(luò)時代全站壓力測試的理想解決方案。
參考文獻:
[1] KOSCHEL A,BERTRAM M,BISCHOF R,et al. A Look at Service Meshes [C]// 2021 12th International Conference on Information, Intelligence, Systems & Applications (IISA).Chania Crete:IEEE,2021:1-8.
[2] WEYUKER E J,VOKOLOS F I. Experience with performance testing of software systems: issues, an approach, and case study [J].IEEE Transactions on Software Engineering,2000,26(12):1147-1156.
[3] MALINA P. Kubernetes Canary Deployment Controllerbc [EB/OL].[2023-03-23].https://dspace.vutbr.cz/bitstream/handle/11012/180400/final-thesis.pdf.
[4] RUDRABHATLA C K. Comparison of zero downtime based deployment techniques in public cloud infrastructure [C]//2020 Fourth International Conference on I-SMAC (IoT in Social, Mobile, Analytics and Cloud) (I-SMAC).Palladam:IEEE,2020:1082-1086.
[5] BINDER W,HULAAS J,MORET P. Advanced Java bytecode instrumentation [C]//Proceedings of the 5th international symposium on Principles and practice of programming in Java.Lisboa Portugal:Association for Computing Machinery,2007:135-144.
作者簡介:陳皓(1976—),男,漢族,云南昆明人,資深系統(tǒng)架構(gòu)師,本科,主要研究方向:大規(guī)模分布式計算系統(tǒng)及云原生架構(gòu);張博民(1977—),男,漢族,河北雄縣人,資深系統(tǒng)架構(gòu)師,碩士,主要研究方向:服務(wù)網(wǎng)關(guān)和服務(wù)網(wǎng)絡(luò)。
收稿日期:2023-04-23