go gRPC 、gateway 简单使用 gRPC 简单使

gRPC 简单使用

Server端代码 github.com/Charlotte32…

Client端代码 github.com/Charlotte32…

  1. 安装 protobuf

1
bash复制代码brew install protobuf
  1. 创建一个go 程序

1
bash复制代码go mod init moudleName
  1. 安装grpc

1
bash复制代码go get -u google.golang.org/grpc
  1. 安装 protobuf 插件(protoc-gen-go),用来生成 pb.go pb_grpc.go

1
2
bash复制代码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

  1. 编写.proto文件

语法文档: developers.google.com/protocol-bu…

1
2
bash复制代码touch Hello.proto
vi Hello.proto
1
2
3
4
5
6
7
8
9
10
11
12
protobuf复制代码syntax = "proto3"; //版本号
package services; // 生成的文件放到哪个包

option go_package = "nsqk.com/rpc";

message SayHelloRequest{
string name = 1;
}

message HelloReplay{
string message = 1;
}
  1. 生成对应的pb.go 文件

1
2
3
4
5
bash复制代码cd ..
# 创建一个services 文件夹,因为proto文件中的package写的是services
mkdir services
cd pb/
protoc --go_out=../services Hello.proto
  1. 编写对应的rpc service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protobuf复制代码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) {}
}
  1. 生成.pb_grpc 文件

1
2
3
4
5
bash复制代码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. 安装

  1. 新建一个tool 文件夹,下面创建一个tool.go
  2. 引入需要的包
1
2
3
4
5
6
7
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"
)
  1. go mod tidy
  2. 安装插件到go bin目录中‘
1
2
3
4
5
bash复制代码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
  1. google 这个文件夹拷贝到pb文件夹下方
1
bash复制代码cp /Users/jr/go/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.16.0/third_party/googleapis/google ./pb/

googleapis
2. 新建一个Prod.proto


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
protobuf复制代码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}"
};
}

}
  1. 重新生成 pb.go _grpc.pb.go,和生成新的gateway需要的pb.gw.go

生成Prod.pb.goProd_grpc.pb.go

1
2
3
bash复制代码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

1
2
3
4
5
bash复制代码protoc -I . \
--grpc-gateway_out ../services \
--grpc-gateway_opt logtostderr=true \
--grpc-gateway_opt paths=source_relative \
Prod.proto
  1. 编写ProdService 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
go复制代码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")
}
  1. 编写http 服务文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
go复制代码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)
}


}
  1. 启动

  1. 先启动grpcServer
  2. 再启动httpServer

这里grpc 端口是2333 http端口是23333

结尾

到此,http 和 grpc 都可以进行访问了

image.png

demo代码地址 :

​ client :github.com/Charlotte32…

​ server: github.com/Charlotte32…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%