首页>>后端>>Golang->使用 grpcurl 通过命令行访问 gRPC 服务

使用 grpcurl 通过命令行访问 gRPC 服务

时间:2023-11-30 本站 点击:0

一般情况下测试 gRPC 服务,都是通过客户端来直接请求服务端。如果客户端还没准备好的话,也可以使用 BloomRPC 这样的 GUI 客户端。

如果环境不支持安装这种 GUI 客户端的话,那么有没有一种工具,类似于 curl 这样的,直接通过终端,在命令行发起请求呢?

答案肯定是有的,就是本文要介绍的 gRPCurl

gRPC Server

首先来写一个简单的 gRPC Server:

helloworld.proto:

syntax="proto3";packageproto;//Thegreetingservicedefinition.serviceGreeter{//SendsagreetingrpcSayHello(HelloRequest)returns(HelloReply){}}//Therequestmessagecontainingtheuser'sname.messageHelloRequest{stringname=1;}//TheresponsemessagecontainingthegreetingsmessageHelloReply{stringmessage=1;}

main.go

packagemainimport("context""fmt""grpc-hello/proto""log""net""google.golang.org/grpc""google.golang.org/grpc/reflection")funcmain(){lis,err:=net.Listen("tcp",":50051")iferr!=nil{log.Fatalf("failedtolisten:%v",err)}server:=grpc.NewServer()//注册grpcurl所需的reflection服务reflection.Register(server)//注册业务服务proto.RegisterGreeterServer(server,&greeter{})fmt.Println("grpcserverstart...")iferr:=server.Serve(lis);err!=nil{log.Fatalf("failedtoserve:%v",err)}}typegreeterstruct{}func(*greeter)SayHello(ctxcontext.Context,req*proto.HelloRequest)(*proto.HelloReply,error){fmt.Println(req)reply:=&proto.HelloReply{Message:"hello"}returnreply,nil}

运行服务:

gorunmain.goserverstart...

grpcurl 安装

这里我介绍三种方式:

Mac

brewinstallgrpcurl

Docker

#Downloadimagedockerpullfullstorydev/grpcurl:latest#Runthetooldockerrunfullstorydev/grpcurlapi.grpc.me:443list

go tool

如果有 Go 环境的话,可以通过 go tool 来安装:

goinstallgithub.com/fullstorydev/grpcurl/cmd/grpcurl@latest

grpcurl 使用

在使用 grpcurl 时,需要通过 -cert-key 参数设置公钥和私钥文件,表示链接启用了 TLS 协议的服务。

对于没有启用 TLS 协议的 gRPC 服务,通过 -plaintext 参数忽略 TLS 证书的验证过程。

如果是 Unix Socket 协议,则需要指定 -unix 参数。

查看服务列表:

grpcurl-plaintext127.0.0.1:50051list

输出:

grpc.reflection.v1alpha.ServerReflectionproto.Greeter

查看某个服务的方法列表:

grpcurl-plaintext127.0.0.1:50051listproto.Greeter

输出:

proto.Greeter.SayHello

查看方法定义:

grpcurl-plaintext127.0.0.1:50051describeproto.Greeter.SayHello

输出:

proto.Greeter.SayHelloisamethod:rpcSayHello(.proto.HelloRequest)returns(.proto.HelloReply);

查看请求参数:

packagemainimport("context""fmt""grpc-hello/proto""log""net""google.golang.org/grpc""google.golang.org/grpc/reflection")funcmain(){lis,err:=net.Listen("tcp",":50051")iferr!=nil{log.Fatalf("failedtolisten:%v",err)}server:=grpc.NewServer()//注册grpcurl所需的reflection服务reflection.Register(server)//注册业务服务proto.RegisterGreeterServer(server,&greeter{})fmt.Println("grpcserverstart...")iferr:=server.Serve(lis);err!=nil{log.Fatalf("failedtoserve:%v",err)}}typegreeterstruct{}func(*greeter)SayHello(ctxcontext.Context,req*proto.HelloRequest)(*proto.HelloReply,error){fmt.Println(req)reply:=&proto.HelloReply{Message:"hello"}returnreply,nil}2

输出:

packagemainimport("context""fmt""grpc-hello/proto""log""net""google.golang.org/grpc""google.golang.org/grpc/reflection")funcmain(){lis,err:=net.Listen("tcp",":50051")iferr!=nil{log.Fatalf("failedtolisten:%v",err)}server:=grpc.NewServer()//注册grpcurl所需的reflection服务reflection.Register(server)//注册业务服务proto.RegisterGreeterServer(server,&greeter{})fmt.Println("grpcserverstart...")iferr:=server.Serve(lis);err!=nil{log.Fatalf("failedtoserve:%v",err)}}typegreeterstruct{}func(*greeter)SayHello(ctxcontext.Context,req*proto.HelloRequest)(*proto.HelloReply,error){fmt.Println(req)reply:=&proto.HelloReply{Message:"hello"}returnreply,nil}3

请求服务:

grpcurl-d'{"name":"zhangsan"}'-plaintext127.0.0.1:50051proto.Greeter.SayHello

输出:

packagemainimport("context""fmt""grpc-hello/proto""log""net""google.golang.org/grpc""google.golang.org/grpc/reflection")funcmain(){lis,err:=net.Listen("tcp",":50051")iferr!=nil{log.Fatalf("failedtolisten:%v",err)}server:=grpc.NewServer()//注册grpcurl所需的reflection服务reflection.Register(server)//注册业务服务proto.RegisterGreeterServer(server,&greeter{})fmt.Println("grpcserverstart...")iferr:=server.Serve(lis);err!=nil{log.Fatalf("failedtoserve:%v",err)}}typegreeterstruct{}func(*greeter)SayHello(ctxcontext.Context,req*proto.HelloRequest)(*proto.HelloReply,error){fmt.Println(req)reply:=&proto.HelloReply{Message:"hello"}returnreply,nil}5

-d 参数后面也可以跟 @,表示从标准输入读取 json 参数,一般用于输入比较复杂的 json 数据,也可以用于测试流方法。

grpcurl-d@-plaintext127.0.0.1:50051proto.Greeter.SayHello

可能遇到的错误

可能会遇到三个报错:

1、gRPC Server 未启用 TLS:

报错信息:

packagemainimport("context""fmt""grpc-hello/proto""log""net""google.golang.org/grpc""google.golang.org/grpc/reflection")funcmain(){lis,err:=net.Listen("tcp",":50051")iferr!=nil{log.Fatalf("failedtolisten:%v",err)}server:=grpc.NewServer()//注册grpcurl所需的reflection服务reflection.Register(server)//注册业务服务proto.RegisterGreeterServer(server,&greeter{})fmt.Println("grpcserverstart...")iferr:=server.Serve(lis);err!=nil{log.Fatalf("failedtoserve:%v",err)}}typegreeterstruct{}func(*greeter)SayHello(ctxcontext.Context,req*proto.HelloRequest)(*proto.HelloReply,error){fmt.Println(req)reply:=&proto.HelloReply{Message:"hello"}returnreply,nil}7

解决:

请求时增加参数:-plaintext,参考上面的命令。

2、服务没有启动 reflection 反射服务

报错信息:

packagemainimport("context""fmt""grpc-hello/proto""log""net""google.golang.org/grpc""google.golang.org/grpc/reflection")funcmain(){lis,err:=net.Listen("tcp",":50051")iferr!=nil{log.Fatalf("failedtolisten:%v",err)}server:=grpc.NewServer()//注册grpcurl所需的reflection服务reflection.Register(server)//注册业务服务proto.RegisterGreeterServer(server,&greeter{})fmt.Println("grpcserverstart...")iferr:=server.Serve(lis);err!=nil{log.Fatalf("failedtoserve:%v",err)}}typegreeterstruct{}func(*greeter)SayHello(ctxcontext.Context,req*proto.HelloRequest)(*proto.HelloReply,error){fmt.Println(req)reply:=&proto.HelloReply{Message:"hello"}returnreply,nil}8

解决:

这行代码是关键,一定要包含:

packagemainimport("context""fmt""grpc-hello/proto""log""net""google.golang.org/grpc""google.golang.org/grpc/reflection")funcmain(){lis,err:=net.Listen("tcp",":50051")iferr!=nil{log.Fatalf("failedtolisten:%v",err)}server:=grpc.NewServer()//注册grpcurl所需的reflection服务reflection.Register(server)//注册业务服务proto.RegisterGreeterServer(server,&greeter{})fmt.Println("grpcserverstart...")iferr:=server.Serve(lis);err!=nil{log.Fatalf("failedtoserve:%v",err)}}typegreeterstruct{}func(*greeter)SayHello(ctxcontext.Context,req*proto.HelloRequest)(*proto.HelloReply,error){fmt.Println(req)reply:=&proto.HelloReply{Message:"hello"}returnreply,nil}9

3、参数格式错误:

报错信息:

gorunmain.goserverstart...0

解决:

-d 后面参数为 json 格式,并且需要使用 '' 包裹起来。

总结:

用这个工具做一些简单的测试还是相当方便的,上手也简单。只要掌握文中提到的几条命令,基本可以涵盖大部分的测试需求了。


扩展阅读:

https://appimage.github.io/BloomRPC/

https://github.com/fullstorydev/grpcurl

文章中的脑图和源码都上传到了 GitHub,有需要的同学可自行下载。

地址: https://github.com/yongxinz/gopher/tree/main/blog


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Golang/4580.html