压测gRPC微服务

微服务压测功能可以用于压测构建于VPC内的微服务应用,通过PTS界面的配置,可以快速实现微服务压测。本文介绍如何对gRPC微服务进行压测。

背景信息

经典微服务架构是通过网关暴露每一个服务,且通过网络隔离来保障每个服务的安全性,因此云上微服务通常构建于安全性较高的VPC网络内。但压测VPC内的微服务应用会面临着网络隔离的难题,传统的解决方案是基于VPC网络搭建压测工具进行压测,例如JMeter压测工具。但搭建JMeter需要一定的时间成本和代码基础,且对微服务压测的支持不友好。PTS自研的微服务压测功能可以帮助您解决这些难题,通过PTS控制台的简单配置,快速实现微服务的压测。

功能入口

  1. 登录PTS控制台,选择性能测试 > 创建场景,然后单击gRPC压测

  2. 创建GRPC场景页面,填写场景名,然后单击上传proto文件,上传相关proto文件。

    说明

    若上传同名文件,则会覆盖之前上传的文件;若需要对比文件,可在该文件的操作列,获取MD5值,与本地文件的MD5值进行对比,确认文件是否变更。

  3. 场景配置页签下,单击+添加gRPC请求节点,为目标业务会话添加所需的测试节点。

场景配置

单击业务会话右侧的ryi图标,展开业务会话,并配置基本信息、出参、检查点等信息。

参数

描述

示例

服务地址

gRPC服务的IP地址。

127.0.0.1

服务端口

gRPC服务的端口号。

50051

请求超时时间

施压端等待被压测端响应的时间限制,单位为毫秒。

5000

SSL/TLS

是否建立安全连接。

方法名

gRPC方法的全名。

说明

格式为包名.接口名/方法名

package.service/method

元数据

类似HTTP Header,格式为key:value

a:1,b:2

说明

多个元数据以半角逗号(,)分隔。

JSON格式请求

以JSON格式描述proto文件中的message。

{
     "shelf": {
        "id": 1,
        "theme": "hello"
        }
 }

出参设置

在串联链路的出参设置页签设置出参。具体操作,请参见接口出参

检查点设置

在串联链路的检查点设置页签设置检查点。具体操作,请参见检查点(断言)

(可选)控制器和定时器

您可以根据不同压测场景的需求,添加控制器和定时器。

  • 场景配置页签下,单击+添加控制器选择所需的控制器。

    • 循环控制器:控制所含测试节点应循环执行的次数。

      选择循环控制器后,单击其右侧的循环控制器的更多图标图标,选择添加需循环执行的测试节点,并设置循环次数。压测时,会将此循环控制器下的测试节点按序执行设置的次数。

    • 事务控制器:事务控制器下所包含的所有测试节点将会被算作为一个事务。其包含生成父样本是否包含样品中定时器和前后程序的持续时间两个设置项。

      • 生成父样本

        • 开启开关:该事务控制器下各测试节点自身的压测结果不会在压测报告中独立输出,而会被聚合作为事务控制器的结果呈现在报告中。

        • 关闭开关:该事务控制器以及其包含的测试节点的压测结果均会显示在报告中。

      • 是否包含样品中定时器和前后程序的持续时间:若选择开启此开关,则压测报告中事务控制器的平均响应时间为所有测试节点和定时器平均响应时间之和。若不开启此开关,则事务控制器的平均响应时间仅为所有测试节点平均响应时间之和。

    • 仅一次控制器:仅一次控制器下添加的节点仅会被执行一次。

  • 场景配置页签下,单击+添加定时器选择所需的定时器。

    • 常量定时器:可设置停顿时长,表示压测过程中,在此处停顿的时长,单位为毫秒。

    • 同步定时器:可设置停顿时长模拟用户数,表示在一定时间内先等待达到一定用户数,然后触发测试,但若在设定时间内未达到指定用户数,则不会继续等待,直接触发测试。

    • 统一随机定时器:统一随机定时器用于控制停顿时长,可设置延迟基准可变跨度。延迟基准为固定停顿时间,可变跨度为随机停顿时间的最大值。统一随机定时器的停顿时长为延迟基准所设的固定停顿时间加上可变跨度所设时间范围内的随机值。各随机值出现的概率相等。

    • 高斯定时器:高斯定时器与统一随机定时器类似,同样用于设置停顿时长,可设置延迟基准可变跨度。若要求随机停顿时间符合正态分布,可使用高斯定时器。

    • 固定吞吐量定时器:固定吞吐量定时器用于控制吞吐量,使测试节点按照吞吐量执行。可设置条件和对应的吞吐量。条件包含仅当前线程所有活跃线程当前链路下活跃线程全局活跃线程当前链路下全局活跃线程

施压配置

压测配置

描述

压力来源

  • 公网:发起压测的节点来自全球各地,根据压测的量级来分配对应的节点资源(IP)。

  • 阿里云VPC内网:阿里云VPC内网压测是指施压机与被压测服务器在相同地域,通过阿里云VPC内网进行压测。更多信息,请参见阿里云VPC内网压测

压力模式

  • 虚拟用户模式:如果您需要从客户端的角度出发,了解业务系统各节点能同时承载的在线用户数,可以使用该模式设置目标虚拟用户。

  • RPS模式:RPS模式即吞吐量模式,通过设置每秒发出的请求数,帮助您从服务端的角度出发,直接衡量系统的吞吐能力,免去从虚拟用户到RPS的繁琐转化,可快速实现压测。

递增模式

  • 手动调速:虚拟用户数是固定的。对应的压力预估图是一条平直线,即设置多少虚拟用户数,会一直按这个虚拟用户数来进行压测。

  • 阶梯递增:虚拟用户数以阶梯递增的方式进行压测。就是对系统施压的虚拟用户数呈现阶梯性增加的过程,每个时间段虚拟用户数都要增加一个数量值,最终达到一个预期的虚拟用户数,然后保持该虚拟用户数,持续运行一段时间。对应的压力预估图是阶梯形式的曲线图。

最大虚拟用户数

虚拟用户模式下,需要指定全场景的最大虚拟用户数。

虚拟用户数

虚拟用户发起请求的个数。例如:设置为100就是100个虚拟用户同时发起了请求。

递增百分比

阶梯递增模式下,需要指定递增百分比。

单量级持续时长

阶梯递增模式下,为保证能在单量级持续过程中发现业务问题,单量级持续时长至少设置1分钟。

压测总时长

自动递增时,总时长 >= 单量级持续时长/递增量级 * 1.1 (向上取整),但不可超过24小时。

指定IP数

指定压测来源的IP个数。具体详情,请参见指定施压IP数

流量地域定制

通过指定施压机的地理位置,即可模拟当地的用户流量。开启后可对施压机地域分布进行配置,从而实现施压流量地域分布的定制化。具体详情,请参见定制地域流量

启动压测

  • 单击保存去压测,在温馨提示页面,选择立即执行并勾选确认本次压测已获得准许并遵守当地法律,然后单击启动压测

  • 调试场景可验证配置是否合理,避免压测失败。若需进行场景调试,单击调试场景即可进入场景调试页面。更多信息,请参见调试场景

分析压测结果

压测结束后,系统会自动获取压测数据,例如压测场景指标、业务详情数据、监控详情数据和API采样日志等,生成压测报告。更多信息,请参见查看PTS压测报告

场景示例

此处以具体的proto文件为例,介绍如何创建正确的gRPC压测场景。

  1. 上传定义gRPC服务和方法的proto文件。假设需压测的方法为CreateShelf,则定义该方法的proto文件如下。

    syntax = "proto3";
    
    package bookstore;
    
    service Bookstore {
      rpc ListShelves (google.protobuf.Empty) returns (ListShelvesResponse) {}
      rpc CreateShelf (CreateShelfRequest) returns (Shelf) {}
    }
    
    message ListShelvesResponse {
      repeated Shelf shelves = 1;
    }
    
    message CreateShelfRequest {
      Shelf shelf = 1;
    }
  2. 创建GRPC场景页面,单击上传proto文件,上传相应的proto文件。image

  3. 在PTS控制台中完成其它gRPC场景配置操作后,单击保存去压测

    • 方法名:bookstore.Bookstore/CreateShelf。

      说明

      根据proto文件代码得到:包名为bookstore,接口名为Bookstore,方法名为CreateShelf,所以在基本配置的方法名一栏应填写:bookstore.Bookstore/CreateShelf。

    • JSON格式请求:

      {
        "shelf": {
          "id": 1,
          "theme": "hello"
        }
      }

      上述请求代码因CreateShelf的传参为CreateShelfRequest,其中自定义字段shelf:

      syntax = "proto3";
      
      package bookstore;
      
      message Shelf {
        int64 id = 1;
        string theme = 2;
      }