Go-micro学习笔记(2)gRPC使用
使用gRPC构建一个简易的商品服务注册到etcd中
创建models/protos目录,新建商品模型
1syntax = "proto3";
2package models;
3
4// 商品模型
5message ProdModel{
6 // @inject_tag: json:"pid"
7 int32 ProdId = 1;
8 // @inject_tag: json:"pname"
9 string ProdName = 2;
10}
使用protoc创建服务
1syntax = "proto3";
2package models;
3
4import "models.proto";
5
6message ProdRequest{
7 int32 size = 1;
8}
9
10message ProdListResponse{
11 repeated ProdModel data = 1;
12}
13
14service ProdService{
15 rpc GetProdList(ProdRequest) returns (ProdListResponse);
16}
使用protoc生成go文件
1cd models/protos
2protoc --go_out=../ models.proto
3protoc --micro_out=../ --go_out=../ prodService.proto
4protoc-go-inject-tag --input=../models.pb.go
新建一个包用于实现ProdService服务
1package prods
2
3import (
4 "context"
5 "grpc_server/models"
6 "strconv"
7)
8
9// 服务实现
10type ProdService struct {}
11
12func newProd(id int32, pname string) *models.ProdModel{
13 return &models.ProdModel{ProdId:id, ProdName:pname}
14}
15
16// 获取商品列表
17func (*ProdService) GetProdList(ctx context.Context,in *models.ProdRequest,res *models.ProdListResponse) error{
18 models := make([]*models.ProdModel,0)
19 var i int32
20 for i=0;i<in.Size;i++{
21 models = append(models, newProd(100 +i, "prodName"+ strconv.Itoa(100+int(i))))
22 }
23 res.Data = models
24 return nil
25}
main.go主函数
1package main
2
3import (
4 "github.com/micro/go-micro/v2"
5 "github.com/micro/go-micro/v2/registry"
6 "github.com/micro/go-micro/v2/registry/etcd"
7 "grpc_server/models"
8 "grpc_server/prods"
9)
10
11func main(){
12
13 etcdReg := etcd.NewRegistry(
14 registry.Addrs("127.0.0.1:2379"),
15 )
16
17 app := micro.NewService(
18 micro.Name("api.hzde.com.testService"),
19 micro.Address("127.0.0.1:8000"),
20 micro.Registry(etcdReg),
21 )
22
23 app.Init()
24 err := models.RegisterProdServiceHandler(app.Server(), new(prods.ProdService))
25 if err != nil{
26 panic(err)
27 }
28 app.Run()
29}
目录结构如下
1.
2├── gen.sh
3├── go.mod
4├── go.sum
5├── main.go
6├── models
7│ ├── models.pb.go
8│ ├── prodService.pb.go
9│ ├── prodService.pb.micro.go
10│ └── protos
11│ ├── models.proto
12│ └── prodService.proto
13└── prods
14 └── prodService.go
运行服务
1go build
2./grpc_server
32020-03-22 11:48:08 level=info Starting [service] api.hzde.com.testService
42020-03-22 11:48:08 level=info Server [grpc] Listening on 127.0.0.1:8000
52020-03-22 11:48:08 level=info Registry [etcd] Registering node: api.hzde.com.testService-69016977-0ea5-4ebd-905d-385400398cb2
看到服务已经注册到etcd中了
etcd查看
1etcdctl get /micro --keys-only --prefix
2/micro/registry/api.hzde.com.testService/api.hzde.com.testService-69016977-0ea5-4ebd-905d-385400398cb2
使用micro工具箱访问gRPC服务
grpc服务已经创建好了,可以创建http服务去调用gRPC服务,如果只是想要验证一下服务,可以直接使用micro工具箱。
1export MICRO_REGISTRY=etcd
2export MICRO_REGISTRY_ADDRESS=127.0.0.1:2379
3micro get service api.hzde.com.testService
输出结果
1service api.hzde.com.testService
2
3version latest
4
5ID Address Metadata
6api.hzde.com.testService-69016977-0ea5-4ebd-905d-385400398cb2 127.0.0.1:8000 protocol=grpc,registry=etcd,server=grpc,transport=grpc,broker=eats
7
8Endpoint: ProdService.GetProdList
9
10Request: {
11 size int32
12}
13
14Response: {
15 data []ProdModel
16}
访问服务
1micro call api.hzde.com.testService ProdService.GetProdList '{"size": 3}'
输出结果
1{
2 "data": [
3 {
4 "ProdId": 100,
5 "ProdName": "prodName100"
6 },
7 {
8 "ProdId": 101,
9 "ProdName": "prodName101"
10 },
11 {
12 "ProdId": 102,
13 "ProdName": "prodName102"
14 }
15 ]
16}
使用micro api创建网关给http访问
1export MICRO_REGISTRY=etcd
2export MICRO_REGISTRY_ADDRESS=127.0.0.1:2379
3export MICRO_API_HANDLER=rpc
4export MICRO_API_NAMESPACE=api.hzde.com
5micro api
程序默认监听在8080端口。
使用curl发送POST请求
1curl -X POST "http://localhost:8080/testService/ProdService/GetProdList" -d '{"size": 5}'
输出结果
1{"data":[{"ProdId":100,"ProdName":"prodName100"},{"ProdId":101,"ProdName":"prodName101"},{"ProdId":102,"ProdName":"prodName102"},{"ProdId":103,"ProdName":"prodName103"},{"ProdId":104,"ProdName":"prodName104"}]}
创建http服务调用gRPC供外部访问
将前面的protos文件拿过来,放到models下,然后重新生成go文件,具体操作略。http通过连接grpc
main.go
1package main
2
3import (
4 "context"
5 "github.com/gin-gonic/gin"
6 "github.com/micro/go-micro/v2"
7 "github.com/micro/go-micro/v2/registry"
8 "github.com/micro/go-micro/v2/registry/etcd"
9 "github.com/micro/go-micro/v2/web"
10 "go-micro/models"
11)
12
13func main() {
14 r := gin.Default()
15 etcdReg := etcd.NewRegistry(
16 registry.Addrs("127.0.0.1:2379"),
17 )
18
19 service := web.NewService(
20 web.Name("testService.client"),
21 web.Address("127.0.0.1:9000"),
22 web.Handler(r),
23 web.Registry(etcdReg),
24 )
25
26 myService := micro.NewService(micro.Name("tetsService.client"))
27 prodService := models.NewProdService("api.hzde.com.testService", myService.Client())
28 v1Group := r.Group("/v1")
29 {
30 v1Group.Handle("POST", "/prods", func(c *gin.Context) {
31 var prodReq models.ProdRequest
32 err := c.Bind(&prodReq)
33 if err != nil {
34 c.JSON(500, gin.H{
35 "status": err.Error()})
36 } else {
37 prodRes, _ := prodService.GetProdList(context.Background(), &prodReq)
38 c.JSON(200, gin.H{
39 "data": prodRes.Data,
40 })
41 }
42 })
43 }
44
45 service.Init()
46 service.Run()
47}
运行服务,使用curl进行测试
1curl -X POST --form Size=4 http://127.0.0.1:9000/v1/prods
输出结果
1{"data":[{"pid":100,"pname":"prodName100"},{"pid":101,"pname":"prodName101"},{"pid":102,"pname":"prodName102"},{"pid":103,"pname":"prodName103"}]}
或者使用json请求
1curl -X POST -H "Content-Type:application/json" http://127.0.0.1:9000/v1/prods -d '{"size": 4}'
输出结果跟上面一样。
- 原文作者:黄忠德
- 原文链接:https://huangzhongde.cn/post/Golang/go-micro_note2/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。