gRPC 简单使用
Server端代码 github.com/Charlotte32…
Client端代码 github.com/Charlotte32…
1. 安装 protobuf
brew install protobuf
2. 创建一个go 程序
go mod init moudleName
3. 安装grpc
go get -u google.golang.org/grpc
4. 安装 protobuf 插件(protoc-gen-go),用来生成 pb.go pb_grpc.go
go get -u google.golang.org/protobuf/cmd/protoc-gen-go
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
安装后可以到 go env GOPATH
里面的bin
目录去查看 是否生成了protoc-gen-go
5. 编写.proto文件
语法文档: developers.google.com/protocol-bu…
touch Hello.proto
vi Hello.proto
syntax = "proto3"; //版本号
package services; // 生成的文件放到哪个包
option go_package = "nsqk.com/rpc";
message SayHelloRequest{
string name = 1;
}
message HelloReplay{
string message = 1;
}
6. 生成对应的pb.go 文件
cd ..
# 创建一个services 文件夹,因为proto文件中的package写的是services
mkdir services
cd pb/
protoc --go_out=../services Hello.proto
7. 编写对应的rpc service
syntax = "proto3"; //版本号
package services; // 生成的文件放到哪个包
option go_package = "nsqk.com/rpc";
message SayHelloRequest{
string name = 1;
}
message HelloReplay{
string message = 1;
}
// 下面编写rpc 接口
service HelloWorld{
rpc HelloRPC (SayHelloRequest) returns (HelloReplay) {}
}
8. 生成.pb_grpc 文件
cd pb
protoc --go_out=../services --go_opt=paths=source_relative \
--go-grpc_out=../services --go-grpc_opt=paths=source_relative \
Hello.proto
gRPC-getway 同时提供RESTful 和 grpc接口
证书相关的操作 juejin.cn/post/702550…
1. 安装
- 新建一个tool 文件夹,下面创建一个tool.go
- 引入需要的包
package tool
import (
_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway"
_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
_ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
)
-
go mod tidy
-
安装插件到
go bin
目录中‘go install \ github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \ github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \ google.golang.org/protobuf/cmd/protoc-gen-go \ google.golang.org/grpc/cmd/protoc-gen-go-grpc
-
把
google
这个文件夹拷贝到pb
文件夹下方cp /Users/jr/go/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.16.0/third_party/googleapis/google ./pb/
2. 新建一个Prod.proto
syntax = "proto3"; //版本号
package services; // 生成的文件的包名
option go_package = ".;services"; //用来覆盖上面的package名称 ;前面是路径
import "google/api/annotations.proto";
message ProdRequest{
int32 prod_id = 1; // 商品id
}
message ProdResponse{
int32 prod_stock = 1; // 库存
}
message QuerySize{
int32 size = 1; //页尺寸
}
message ProdResponseList{ // 返回商品库存列表
repeated ProdResponse prodres = 1;
}
service ProdService{
rpc GetProdStock(QuerySize) returns (ProdResponseList){
option (google.api.http) = {
get: "/v1/prod/{size}"
};
}
}
3. 重新生成 pb.go
_grpc.pb.go
,和生成新的gateway需要的pb.gw.go
生成
Prod.pb.go
、Prod_grpc.pb.go
cd pb && protoc --go_out=../services --go_opt=paths=source_relative \
--go-grpc_out=../services --go-grpc_opt=paths=source_relative \
Hello.proto
生成
Prod.pb.gw.go
protoc -I . \
--grpc-gateway_out ../services \
--grpc-gateway_opt logtostderr=true \
--grpc-gateway_opt paths=source_relative \
Prod.proto
4. 编写ProdService 文件
package services
import (
"context"
"log"
)
type ProdService struct {
}
func (p *ProdService)GetProdStock(ctx context.Context, req *QuerySize) (*ProdResponseList, error){
log.Println(req.Size)
return &ProdResponseList{Prodres: []*ProdResponse{&ProdResponse{ProdStock: 2333}}},nil
}
func (p *ProdService)mustEmbedUnimplementedProdServiceServer(){
log.Fatalln("含有未实现的service")
}
5. 编写http 服务文件
package main
import (
"context"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"log"
"net/http"
"nsqk.com/rpc/helper"
"nsqk.com/rpc/services"
)
func main() {
ctx := context.Background()
ctx,cancel := context.WithCancel(ctx)
defer cancel()
// 创建一个gateway mux
gwmux := runtime.NewServeMux()
// 创建grpc client dial 配置项
// 这里把RESTful api 转成 gRPC client 去请求,所以传入客户端的证书
opt := []grpc.DialOption{grpc.WithTransportCredentials(helper.GetClientCreds())}
// 注册并且设置http的handler,这里传入的endpoint 是gRPC server的地址
err := services.RegisterHelloWorldHandlerFromEndpoint(ctx,gwmux,"localhost:2333",opt)
if err != nil{
log.Fatalln("注册hello grpc转发失败:",err)
}
err = services.RegisterProdServiceHandlerFromEndpoint(ctx,gwmux,"localhost:2333",opt)
if err != nil{
log.Fatalln("注册prod grpc转发失败:",err)
}
httpServer := &http.Server{
Addr: ":23333",
Handler: gwmux,
}
err = httpServer.ListenAndServe()
if err != nil{
log.Fatalln("http 启动失败:",err)
}
}
6. 启动
- 先启动grpcServer
- 再启动httpServer
这里grpc 端口是2333
http端口是23333
结尾
到此,http 和 grpc 都可以进行访问了
demo代码地址 :
client :github.com/Charlotte32…
server: github.com/Charlotte32…