陳皓 張博民



摘? 要:隨著硬件性能的提升、網絡帶寬的增加和數據量的急劇增長,傳統的單機應用已無法滿足現代企業的需求,取而代之的是基于分布式的軟件系統。這些軟件系統在提供強大計算能力的同時,也引入了復雜性。文章介紹一種新型的基于云原生架構的生產線上全鏈路壓力測試方法——Shadow Service,通過實現業務一致性、數據一致性、資源一致性和各種隔離性,保證了測試結果的準確性和生產系統的安全性。同時,詳細介紹了如何在一個簡化后的訂單支付場景中使用Shadow Service實現壓力測試。
關鍵詞:生產環境;壓力測試;影子服務;服務網格;云原生
中圖分類號:TP311.5? 文獻標識碼: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? 引? 言
在網絡時代,一個大型的互聯網應用需要承受數以億計的訪問量,這需要我們對應用中所有的服務進行全面完整的全鏈路壓力測試,但這面臨著巨大的挑戰,傳統測試方法不僅成本高昂且無法保證準確性,還需要巨大的工作量并存在破壞生產系統的風險。為了應對這些問題,MegaEase提出了Shadow Service技術,基于云原生的流量調度和Service Mesh技術,實現了業務一致、數據一致、資源一致以及業務隔離、數據隔離、流量隔離和資源隔離。這種方法不需要修改任何代碼,成本低,能夠保證業務邏輯與生產環境的一致性,同時可以使用生產數據進行測試,保證測試結果的準確性,且安全可靠。因此,Shadow Service成為網絡時代全站壓力測試的理想選擇。
1? 背景介紹
隨著硬件性能越來越強,帶寬越來越高,數據越來越多,傳統的單機應用已經無法滿足用戶需求,取而代之的是由各種組件基于網絡而構成的軟件系統。
但這種軟件系統,在帶來更強大的計算能力的同時,也引入了單機時代所不具有的復雜性。今天,一個完整的軟件系統,模塊數量少則幾十,多則成千上萬。并且,為了提高開發上線速度,這些模塊會由不同的團隊使用不同的語言開發,這也讓模塊間的通信變得更加復雜。
同時,今天的業務模式相比過去也發生了很大的變化,類似雙十一的促銷活動,會讓系統承受數倍、數十倍于日常的壓力。所以,壓力測試變得日益重要,但傳統的測試方法也變得越來越無法適應業務需求。
2? 問題和難點
2.1? 專用測試環境的問題
在單機時代,使用“1:1”的測試環境,是非常好的壓力測試方法。但到了網絡時代,這種做法卻可能非常不切實際。
1)成本問題。要測試單機軟件,即使是獨立開發者,絕大多數情況下也可以輕松地購買一臺獨立的測試用計算機;但今天的系統所需的資源太多了,要想1:1的按照生產系統搭建一套測試系統,單是服務器成本就會高的讓大多數公司難以承受,更不用說還可能有帶寬、電力、機房等費用。
2)環境問題。即使我們在成本上沒有問題,但是真的“1:1”建起測試環境,保持這個測試環境與生產環境的軟件、數據完全一致也充滿挑戰。在實際工作中,測試環境與生產環境的差異會隨著時間的推移越來越大,最終導致測試結果失真。
3)數據問題。我們還會面對測試數據的問題,如果不能保證測試環境的數據與生產環境接近甚至相同,測試結果就不可信。比如一個類似微博的系統,像作者這種普通用戶一般只有幾十或幾百人關注,所以我發一條消息,隨便怎么做都可以很容易地通知所有關注者。但對一個千萬大V,情況就會截然不同。所以,我們不能簡單地使用模擬數據進行測試。
4)安全問題。為了讓測試結果真實可靠,最好能夠把完整的生產數據導入到測試環境。乍看上去,這只需要簡單地備份恢復下數據庫,但生產環境包含大量敏感數據,隨意復制到測試環境無疑會極大地增加數據泄露的風險。
2.2? 在生產環境進行測試的問題
因為使用測試環境進行壓測存在諸多困難,人們就把目光轉向了生產環境,嘗試直接利用生產環境上的壓力低谷時段,比如凌晨,進行測試。但這是一種侵入式的解決方案,涉及修改甚至重新定義業務邏輯,所以同樣面臨巨大挑戰。
假設我們要修改的是一個網購系統,那么用戶購物下訂單的流程應該會涉及用戶、訂單、支付等一系列的模塊。
1)如果我們要修改用戶模塊,那么我們需要用代碼判斷過來的請求是應該走測試邏輯還是生產邏輯。比較常見的方法是預先指定一個用戶ID的范圍,如果是這個范圍的用戶,就走測試邏輯,否則走生產邏輯。
2)用戶模塊之后,邏輯走到了訂單模塊,這時,我們可能仍然希望通過用戶ID來判斷是否應該走測試邏輯,但實際情況卻可能是:經過一系列的復雜處理流程,訂單模塊根本看不到用戶信息,所以此路不通。
3)為了讓訂單模塊能區分出正常訂單和測試訂單,就必須在用戶模塊增加一些處理邏輯,比如給訂單號加上特殊標記等。但是,在一個復雜的系統里,用戶模塊并不容易知道后續流程要經過的所有模塊,所以,為了不影響正常的生產邏輯,僅僅保證測試狀態的正常傳遞就需要付出不小的努力,更不用說還要考慮是否要訪問不同的數據集,是否要模擬第三方服務等各種情況。
很明顯,這種業務邏輯的修改,所需的工作量與功能點數量成正比。但除了巨大的工作量,更嚴重的問題是,在辛苦的修改之后,有誰能保證所有需要做的修改都改了,并且改對了?而萬一有遺漏或錯誤,就有可能破壞生產系統,這個風險實在是太大了,我們很難承受。
3? 解決之道
3.1? 一致性和隔離性
從前面的分析可以看出,傳統的測試方法或者成本高昂且得不到準確的數據,或者工作量巨大且存在破壞生產系統的風險。因此,MegaEase認為,要解決網絡時代的全站壓力測試問題,必須使用一種全新的方法,而這種方法的關鍵在于“三一致”和“四隔離”。
“三一致”是指業務一致、數據一致和資源一致。也就是說,測試系統和生產系統應該完全相同,只有這樣,才能得到準確的測試數據。現實地說,100%的一致并不容易做到,比如,我們通常無法要求第三方配合我們進行測試,所以,只能使用模擬的方法替換掉部分第三方依賴。但我們仍然需要盡最大可能保證兩個系統的一致性。
“四隔離”是指業務隔離、數據隔離、流量隔離和資源隔離。這些隔離,都是為了將生產系統和測試系統完全分開,避免它們相互影響。很顯然,三一致解決的是測試結果的準確性問題,而四隔離則保證了測試過程不會影響生產系統。
基于上面的定義,我們可以使用一種叫Shadow Service的技術,其主要利用云原生中的SideCar和Service Mesh技術。通過Shadow Service,我們可以非常容易地為系統中的所有的應用服務創建一個影子(Shadow)副本,除了帶有Shadow標記之外,這些影子副本與原始服務完全相同,從而保證了業務一致和業務隔離。同時,Shadow Service還會自動創建一條流量分配規則,將帶有特殊標記的流量,比如,我們在用于測試的請求協議頭中加上一個標志Request-Header: Test,通過Shadow Service的Mesh Ingress組件,將此請求作為測試請求轉發到服務副本,將其他沒有該標識的請求發送給原始服務,以實現流量隔離。
在數據方面,Shadow Service可以根據配置替換掉包括MySQL、Kafka、Redis等在內的多種中間件的連接信息,并借此改變數據請求的發送目標,這保證了數據隔離。而用戶則可以直接將生產數據復制一份作為測試數據來保證數據一致。
資源一致和資源隔離是指測試系統要使用與生產系統規格相同的資源,但不應該共享同一套資源。這主要是一個硬件問題,但Kubernetes已經在軟件層面給出了非常好的答案,而Shadow Service是建立在Kubernetes之上,所以,通過將服務副本部署到新的Pod中,資源一致和資源隔離就都得到了保證。
3.2? Shadow Service工作方式
下面我們以一個簡化后的訂單支付的場景,介紹一下Shadow Service的具體使用方法。這個場景涉及訂單(Order)和支付(Payment)兩個服務,訂單服務會調用支付服務,支付服務最終會調用第三方服務(圖中未畫出)來完成支付,同時,訂單服務還會訪問MySQL數據庫。整個系統,通過MegaEase的EaseMesh部署在Kubernetes中,部署過程中,EaseMesh會向應用的Pod中注入的SideCar(基于Easegress)和JavaAgent(基于EaseAgent),從而劫持應用發出的HTTP請求和數據請求,實現前面提到的“三一致”和“四隔離”。系統的總體架構如圖1所示。
要對其進行測試,我們需要首先創建數據庫的副本。這一步,可以通過數據庫的備份恢復功能來完成,如圖2所示,因為數據副本和原始數據位于同一個安全域,所以不必對數據進行脫敏處理。
然后,使用下面的配置通過EaseMesh的命令創建訂單服務的shadow副本和灰度規則。注意,在創建服務的副本時,我們將其使用的數據庫指向了剛剛創建的數據庫副本。最終系統架構如圖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"
最后,因為不想在測試的時候實際支付費用,我們要用下面的命令Mock支付服務。注意,調用第三方支付服務時通常會涉及多個非常復雜的安全驗證步驟,這導致這個服務難以被直接Mock。所以,我們把第三方服務包裝成了系統內部的服務,并借此簡化了調用接口,下面Mock的實際上是這個包裝后的服務:
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"}'
這樣就完成了整個測試系統的創建,我們可以向其發送帶有Request-Header: Test頭部的請求來進行壓力測試。最終的系統架構如圖4所示。
3.3? Shadow Service的優勢
相對于傳統的測試方法,使用Shadow Service進行壓力測試在以下5個方面具有明顯的優勢:
1)0代碼修改:全部通過配置完整,不需要修改任何代碼,沒有改出Bug的風險。
2)低成本:在使用云服務器的情況下,測試用的硬件資源隨用隨申請,用完就釋放,僅需要為實際使用時段付費。
3)業務邏輯與生產環境基本一致:除少數被Mock的服務外,測試系統與生產系統完全一致,最大程度避免了業務邏輯的差異導致的誤差。
4)可以使用生產數據進行測試:測試系統和生產系統的數據完全一致,保證了測試結果的準確性。
5)安全:雖然測試時使用的是生產數據,但測試系統和生產系統處于同一個安全域,所以沒有增加數據泄露風險。
4? 結? 論
通過Service Mesh以及Shadow Service技術把生產環境的應用服務和數據復制出一份用于測試,并通過流量網關進行測試流量的調度,我們可以在極低的成本下,實現業務一致、數據一致、資源一致以及業務隔離、數據隔離、流量隔離和資源隔離,同時,也避免了對代碼的修改,降低了成本,保證了業務邏輯與生產環境的一致性,并可以使用生產數據進行測試,確保了測試結果的準確性和系統安全。因為只需要在付出一定的低成本云計算基礎硬件資源,Shadow Service成為網絡時代全站壓力測試的理想解決方案。
參考文獻:
[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—),男,漢族,云南昆明人,資深系統架構師,本科,主要研究方向:大規模分布式計算系統及云原生架構;張博民(1977—),男,漢族,河北雄縣人,資深系統架構師,碩士,主要研究方向:服務網關和服務網絡。
收稿日期:2023-04-23