# 介绍
# 配置
- 支持配置文件、命令行配置
- 可以指定 proto 源文件或者使用 protoc 生成的 protoset 描述文件
- 支持指定协议名
- 支持导入原始路径列表
- 可以指定秘钥信息
- 可以指定 tls 服务器名称
- 可以跳过 tls
- 是否异步请求,不等待上一个请求完成
- 支持设置 rps
- 支持指定加载进度
- 即可以逐步提高 rps 到预设值
- 可以指定并发工作器数量
- 可以指定并发工作器添加策略
- 即逐步增加工作线程
- 指定请求总数
- 指定超时时间,默认 20,不限制则设为 0
- 指定持续时间
- 指定停止策略:关闭、等待请求返回、忽略则忽略正在运行的请求
- 指定请求体,以 json 格式
- 指定请求体,以文件形式
- 制定请求体,以二进制形式或者二进制文件
- 指定元数据 ,json 字符串或者文件
- 流式接口的传输测试
- …
- 指定连接数,默认一个连接
- 指定初始连接超时时间
- 可以使用的 cpu 内核数
- 指定客户端负载策略
# 输出
- summary
- csv 格式
- html 格式
- json 格式
- prometheus 格式
- influxDB 格式
# 实践
# 一个 grpc 服务 demo
# pb 编写
syntax = "proto3";
package pb;
option go_package="./;pb";
message HelloRequest{
string name = 1;
int32 id = 2;
}
message HelloReply{
string name = 1;
string message = 2;
}
service HelloService{
rpc Hello(HelloRequest) returns (HelloReply);
}
# 生成 go 文件和服务端代码
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative *.proto |
# 写一个服务
package main | |
import ( | |
"context" | |
"fmt" "google.golang.org/grpc" "grpc_demo/pb" "log" "net") | |
const ( | |
port = ":50051" | |
) | |
type myServer struct { | |
pb.UnimplementedHelloServiceServer | |
} | |
func (s *myServer) Hello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) { | |
fmt.Println("hello receice message:", req) | |
rep := &pb.HelloReply{ | |
Name: req.Name, | |
Message: "你好呀", | |
} | |
return rep, nil | |
} | |
func main() { | |
lis, err := net.Listen("tcp", port) | |
if err != nil { | |
log.Fatalf("failed to listen: %v", err) | |
} | |
// 创建一个 gRPC 服务端实例 | |
s := grpc.NewServer() | |
// 注册 | |
pb.RegisterHelloServiceServer(s, &myServer{}) | |
if err := s.Serve(lis); err != nil { | |
log.Fatalf("failed to serve: %v", err) | |
} | |
} |
# 压测实践
其中参数解释
- proto 指定原型
- rps 指定目标 rps 值
- total 指定目标请求数
- call 指定要压的方法名
- data 指定请求体数据 json 格式,也可以是数组,那么会轮流请求给定的请求体
- skipTLS insecure 说明使用明文压测
- 最后是服务地址
结果可以看到
- 总结:总请求数、总消耗时间、最慢请求、最快请求、平均时间、QPS
- 响应时间直方图
- 百分比延迟分布
- 响应码分布
ghz --proto=hello.proto --rps=100 --total=100 --call pb.HelloService.Hello --data='{"name": "xiamu", "id": 1}' --skipTLS --insecure 192.168.31.129:50051 | |
Summary: | |
Count: 100 | |
Total: 1.06 s | |
Slowest: 497.68 ms | |
Fastest: 4.33 ms | |
Average: 189.71 ms | |
Requests/sec: 94.43 | |
Response time histogram: | |
4.334 [1] |∎∎ | |
53.669 [17] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ | |
103.004 [19] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ | |
152.339 [10] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ | |
201.674 [10] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ | |
251.008 [10] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ | |
300.343 [11] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ | |
349.678 [7] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ | |
399.013 [5] |∎∎∎∎∎∎∎∎∎∎∎ | |
448.348 [5] |∎∎∎∎∎∎∎∎∎∎∎ | |
497.683 [5] |∎∎∎∎∎∎∎∎∎∎∎ | |
Latency distribution: | |
10 % in 36.96 ms | |
25 % in 67.50 ms | |
50 % in 166.24 ms | |
75 % in 286.13 ms | |
90 % in 397.86 ms | |
95 % in 448.03 ms | |
99 % in 487.83 ms | |
Status code distribution: | |
[OK] 100 responses | |
~/code/ghz_test ❯ |
# 原理
本质上还是 go 协程来实现的。
各个模块区分的很清晰:
- 请求模块
- 数据处理模块
- 日志模块
- 统计模块
- 输出模块
- 连接管理模块
如果用来做自己的压测工具,并且接入 prometheus 监控应该不需要花太大功夫。
此外如果将其改造为 http 的压测,应该也非难事。
# 未来
代码里面还包含一个 ghz 命令,不过还在开发中,可以期待一下。