在日常开发中,开发人员或测试人员需要评估服务的性能是否符合预期,避免因功能迭代导致服务性能下降而引发故障。服务压测功能可以让您低成本地评估服务性能,做到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(); | [] | [] |