grpc:用ghz进行性能压测
简介:ghz是一个命令行实用程序和Go包,用于负载测试和基准测试gRPC服务。它旨在用于在本地测试和调试服务,以及在自动连续集成环境中进行性能回归测试。此外,命令行工具的核心实现为 Go 库包,也可用于以编程方式实现性能测试。
https://github.com/bojand/ghz
帮助文档:https://ghz.sh/docs/intro.html
安装:
win:下载安装包并解压后配置环境变量。
https://github.com/bojand/ghz/releases
mac:
brew install ghz
相关攻略:参考同期 grpc:go-quickstart
安装protobuf:
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
案例目录:
创建proto文件:
syntax = "proto3";
option go_package = "./pb";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
使用 protoc 编译 proto 文件, 生成 go 语言的实现:
protoc -I . --go_out=plugins=grpc:. ./*.proto
业务逻辑:service/method.go,SayHello和SayHelloAgain必须都实现
package service
import (
"context"
"rpcGoPro/pb"
)
type Hello struct{}
func (hello *Hello) SayHello(ctx context.Context, pkg *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{
Message: pkg.Name + "..go hello...",
}, nil
}
// 对应proto的 rpc方法。SayHello,SayHelloAgain。并且必须两个都实现
func (hello *Hello) SayHelloAgain(ctx context.Context, pkg *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{
Message: pkg.Name + "..go hello again...",
}, nil
}
服务器端:server/server.go
package main
import (
"google.golang.org/grpc"
"log"
"net"
"rpcGoPro/pb"
"rpcGoPro/service"
)
func main() {
addr := "localhost:8889" // 服务地址
listener, err := net.Listen("tcp", addr) // 监听地址
if err != nil {
log.Println("net listen err ", err)
return
}
s := grpc.NewServer() // 初始化grpc服务
pb.RegisterGreeterServer(s, &service.Hello{}) // 注册服务
log.Println("start gRPC listen on address " + addr)
if err := s.Serve(listener); err != nil { // 监听服务,如启动失败则抛出异常
log.Println("failed to serve...", err)
return
}
}
客户端:client/client.go
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"log"
"rpcGoPro/pb"
)
const (
address = "localhost:8889"
)
func main() {
conn, err := grpc.Dial(address, grpc.WithInsecure()) // 建立链接
if err != nil {
log.Println("did not connect.", err)
return
}
defer conn.Close()
client := pb.NewGreeterClient(conn) // 初始化客户端
ctx := context.Background() // 初始化元数据
helloName := &pb.HelloRequest{Name: "Tom"} // 构造请求体
info, err := client.SayHello(ctx, helloName) // 调用helloInfo rpc服务,就像调用普通函数一样
info2, err2 := client.SayHelloAgain(ctx, helloName) // 调用helloInfo rpc服务,就像调用普通函数一样
if err != nil || err2 != nil {
return
}
fmt.Println("hello 1 :", info.Message, "hello 2:", info2.Message)
}
命令行执行压测:
cd rpcPro目录
ghz --insecure --proto=./helloworld.proto --call=Greeter.SayHello -d "{\"name\":\"tom\"}" -c 10 -n 10000 127.0.0.1:8889
参数说明:
包名为helloworld、 service名为Greeter,方法名为 SayHello。
详细参数说明:https://ghz.sh/docs/options
执行结果: