在日常開發中,開發人員或測試人員需要評估服務的性能是否符合預期,避免因功能迭代導致服務性能下降而引發故障。服務壓測功能可以讓您低成本地評估服務性能,做到1分鐘創建壓測場景,5分鐘獲取性能指標。
背景信息
在大促活動中,應該準備多少實例資源才能滿足大促吞吐量的要求,降低因大促活動帶來的訪問量暴增進而引發系統宕機的風險。此時需要合理地評估服務性能,避免流量沖擊引發的故障,并降低運營使用成本。
創建壓測場景
- 登錄EDAS控制臺。
- 選擇Dubbo左側導航欄單擊服務壓測。 。然后在
- 在服務壓測頁面頂部菜單欄選擇地域,在頁面中選擇微服務空間,然后單擊創建場景。
- 在創建場景面板中設置場景配置和壓力配置相關參數,然后單擊確定。
場景配置頁簽相關參數說明如下:
參數 描述 場景名稱 壓測場景名稱,例如test-dubbo。 應用 需要壓測的應用。 框架類型 支持Spring Cloud和Dubbo框架。系統會根據所選應用自動識別其框架,也可以手動選擇Dubbo。 服務 選擇需要壓測的目標服務。 方法 選定服務壓測的方法。 請求參數 設置請求參數。關于Dubbo服務的方法參數類型及配置方式,請參見Dubbo參考示例。 超時時間(毫秒) 設置超時時間,單位:毫秒。 直連服務 通過開關設置是否需要直接連接目標服務。打開開關后,需要設置服務地址。 打印日志 通過開關設置是否需要打印壓測日志,日志中會包含服務異常信息。打開開關后,會影響到服務壓測性能,建議正常壓測(非排查服務異常)時關閉。 壓力配置頁簽相關參數說明如下。
參數 描述 壓測模式 服務壓測包括并發模式和TPS模式。 - 并發模式:指虛擬并發用戶數,從業務角度,也可以理解為同時在線的用戶數。
- TPS模式(Transaction Per Second,吞吐量模式):指系統每秒處理的事務數量。
流量模型 流量模型包括固定壓力、階梯壓力和脈沖壓力。 - 固定壓力:以配置的固定并發值進行施壓,并可設置預熱時長。
- 階梯壓力:設置最大值、最小值、預熱時間等信息,在預熱遞增期間,從最小值開始按照階梯逐步遞增,達到最大并發后按照最大并發持續施壓。不可指定循環次數。
- 脈沖壓力:設置峰值、谷值以及持續時間等信息,施壓流量以峰值、峰谷的鋸齒波的形式進行施壓。
壓測時長(分鐘) 指壓測總時長,公測期間最大壓測時長60分鐘。 預熱時長(分鐘) 施壓前的預熱時間,若設置為0,則表示無需預熱。 壓測場景創建成功后,返回服務壓測列表查看相關信息,包括平均TPS、平均響應時間、錯誤率等。
查看壓測報告
- 登錄EDAS控制臺。
- 選擇Dubbo左側導航欄單擊服務壓測。 。然后在
- 在服務壓測頂部菜單欄選擇地域,在頁面中選擇命名空間,然后在已完成壓測的目標服務的操作列單擊詳情。
- 在詳情面板查看場景配置和運行記錄。
- 在運行記錄區域的操作列單擊詳情,查看實時性能數據。說明 性能數據按固定周期(10秒)統計所有施壓機數據,顯示時間間隔會根據壓測總時間長度會有所變化。單擊圖上方的圖例,可以顯示或隱藏某些數據。
參數 說明 總請求數 整個壓測過程中,共發起的請求個數。 平均TPS 壓測周期內,所有壓力機發出的平均TPS值,TPS=調用總次數/總運行時間。 平均RT(ms) 所有壓力機發出平均響應時間。 最小RT(ms) 所有壓力機中最小的一次響應時間。 最大RT(ms) 所有壓力機中最大的一次響應時間。 錯誤請求數 所有壓力機中錯誤請求數之和。 錯誤率 所有壓力機中的平均錯誤率。 TP80(ms) 所有壓力機中80分位(P80)的平均值。 TP95(ms) 所有壓力機中95分位(P95)的平均值。 TP99(ms) 所有壓力機中99分位(P99)的平均值。
Dubbo參考示例
方法 | 參數類型填寫方式 | 參數填寫方式 |
---|---|---|
String sayHello(String name); | ["java.lang.String"] | ["hello, dubbo"] |
String helloBean(HelloBean helloBean); | ["com.alibaba.dubbo.api.DemoService"] | [{"booleanValue":true,"helloSubValue":{"booleanValue":false,"intValue":2,"stringValue":"subbean"},"intValue":1,"stringValue":"bean"}] |
String helloBean(HelloBean helloBean1, HelloBean helloBean2); | ["com.alibaba.dubbo.api.DemoService","com.alibaba.pts.dubbo.api.DemoService"] | [{"booleanValue":true,"helloSubValue":{"booleanValue":false,"intValue":2,"stringValue":"subbean"},"intValue":1,"stringValue":"bean"},{"booleanValue":true,"helloSubValue":{"booleanValue":false,"intValue":2,"stringValue":"subbean"},"intValue":1,"stringValue":"bean"}] |
String helloMap(Map helloMap); | ["java.util.Map"] | [{"booleanValue":true,"helloSubValue":{"booleanValue":false,"intValue":2,"stringValue":"subbean"},"intValue":1,"stringValue":"bean"}] |
String helloMap(Map helloMap1, Map helloMap2); | ["java.util.Map", "java.util.Map"] | [{"booleanValue":true,"helloSubValue":{"booleanValue":false,"intValue":2,"stringValue":"subbean"},"intValue":1,"stringValue":"bean"},{"booleanValue":true,"helloSubValue":{"booleanValue":false,"intValue":2,"stringValue":"subbean"},"intValue":1,"stringValue":"bean"}] |
String helloList(List helloList); | ["java.util.List"] | [[1]] |
String helloList(List helloList1, List helloList2); | ["java.util.List","java.util.List"] | [[1],[1,2]] |
String helloString(String helloString); | ["java.lang.String"] | [[1],[1,2],[1,3]] |
String helloString(String helloString1, String helloString2); | ["java.lang.String","java.lang.String"] | ["hello, dubbo", "hello, dubbo"] |
String helloInt(int helloInt); | ["int"] | ["hello, dubbo", "hello, dubbo"] |
String helloInt(int helloInt1, int helloInt2); | ["int","int"] | ["1","2"] |
String helloBoolean(boolean helloBoolean); | ["boolean"] | ["true"] |
String helloBoolean(boolean helloBoolean1, boolean helloBoolean2); | ["boolean","boolean"] | ["true","false"] |
String helloVoid(); | [] | [] |