背景
秒殺是我們ServiceComb開源團隊以領域驅動設計(DDD)為背景,從零開始構建一個微服務架構的示例項目;在《秒殺開發歷程》系列博文中提到它作為一個高並發壓力場景的應用,采用了CQRS模式構建,因此我們將使用JMeter來對其進行性能評估。
制定用戶行為模型
因為秒殺的場景在現實生活中非常常見,所以用戶行為模型非常容易設計:
- 客戶不停的刷秒殺活動,直到刷出一個正在進行的秒殺活動;
- 刷出了秒殺活動后,馬上請求秒殺優惠券;
- 無論是否成功,客戶會稍后查詢一次自己已經擁有的優惠券確定優惠券是否進入自己的賬號。
我們還需要一個管理員用戶,隔一段時間就創建發布秒殺活動,當然活動包含的優惠券數量將會遠少於客戶的數量。 用戶行為模型在JMeter中體現為腳本邏輯,完成的腳本邏輯如下:
腳本文件已經托管至秒殺項目中,可直接獲取:
git clone https://github.com/ServiceComb/seckill cd seckill/performance-test/script
性能測試環境
我們調來了兩台雲服務器進行性能測試,角色和配置如下:
秒殺服務器配置
承載秒殺示例所有的微服務和中間件,包括四個微服務(Admin、Command、Event和Query)、兩個數據庫(ReadDB和WriteDB)和一個Message Broker(ActiveMQ)。
配置項 | 配置值 |
---|---|
CPU | Intel Xeon E5-2690 3.0GHz * 16 |
MEM | 64GB |
OS | Ubuntu 16.04.2 LTS |
為了能夠便於配置和啟動示例系統,我們采用《秒殺開發歷程(三)》中的一鍵啟動模式拉起所有的服務,因此Docker升級為當前最新版17.06.2-ce,能夠支持配置Container使用CPU和內存的大小限制,以Admin微服務為例:
admin-service: mem_limit: 4096m cpu_count: 4 cpu_percent: 50 image: "seckill-admin-service:0.2.0-SNAPSHOT" hostname: admin-service links: - "mysql-write-db:write_db.servicecomb.io" environment: - JAVA_OPTS=-Dspring.profiles.active=prd -Dendpoints.shutdown.enabled=true ports: - "8081:8081"
加壓機配置
加壓機與秒殺服務器處於同一網絡環境中,配置如下: | 配置項 | 配置值 | | —- | —————————— | | CPU | Intel Xeon E5-2690 3.0GHz * 16 | | MEM | 32GB | | OS | Ubuntu 16.04.2 LTS |
啟動測試
我們設定測試場景為200客戶,每隔1秒啟動一個新客戶;1個管理員每隔10秒發布1個秒殺活動,一共發布160次,每個秒殺活動包含50張優惠券,即一共投放8000張優惠券。整個測試持續半個小時。 現在,我們切換到性能測試腳本目錄下,執行下面的命令啟動測試:
jmeter -n -t seckill.jmx -l log.jtl
測試結果
測試完畢后通過下面的命令分析測試結果日志數據,請將替換為你的本地目錄:
jmeter -g log.jtl -o <report folder>
我們需要先驗證測試結果的正確性,查看數據統計圖:
其中秒殺的失敗率在96.45%,原因是Query對於活動的秒殺活動采用的是0.5秒刷新緩存的策略,在活動中的優惠券被秒殺一空下架前,短暫的時間內仍然能夠查詢到這個活動;架構中采用的CQRS模式只能保證最終一致性,並不能保證實時一致性。 成功秒殺的次數為225264 - 217264 = 8000,正好等於我們設定的優惠券投放量,其他事務的失敗率均為0%,因此測試結果正確。
吞吐能力
秒殺整體吞吐能力如下圖:
可以看到查詢活躍的秒殺活動(刷券)事務處理量最高,穩定在4000左右,其他因為業務比例的原因較低,去掉查詢活躍的秒殺活動事務后如下圖:
秒殺和優惠券查詢之間的差值是由於存在秒殺失敗造成的,我們的用戶行為模型是無論秒殺成功與否都會進行一次優惠券查詢。
響應時間
事務的響應時間我們可以看下面兩個圖:
75%的事務處理時間都在10ms以下,整體平均響應時間處於50ms以下。
瓶頸分析
依據執行過程中對於測試資源的觀察,加壓機CPU使用率基本已滿(200線程並發),服務器CPU使用率低於20%,其他資源使用率很低。
總結
通過這次性能測試,我們得知秒殺示例在使用一台普通服務器配置能夠達到總體5000以上的TPS還能夠保持較低的資源使用率,表現出良好的性能;未來我們會將秒殺示例部署在K8S群集中並配置彈性伸縮進行壓力測試,您可以閱讀我們《在Kubernetes集群中使用JMeter對Company示例進行壓力測試》這篇文章展望。
出處:https://servicecomb.incubator.apache.org/cn/docs/performance-test-on-seckill-with-jmeter/