go protobuf和grpc | 青训营笔记

79 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天

1 Protobuf

1.1 指定 protobuf 版本

syntax = "proto3";

1.2 指定 protobuf 包

option go_package = ".;proto";

不建议使用:

package proto;  // option go_package = ".;proto"; 会覆盖此选项

1.3 定义 message

message WorldRequest{  
  string s = 1;  // 需要传递的消息
}

message WorldResponse{  
  int32 status_code = 1; // 状态码,0-成功,其他值-失败  
  string status_msg = 2; // 返回状态描述   
}

message 由 message 字段定义,后面紧跟需要定义的消息名称。message 由若干字段组成,每个字段由 类型 字段名=序号 组成。该序号在客户端和服务端需要和字段名一一对应,否则将解析失败。

1.4 定义 rpc 服务

service Hello{  
  rpc World(WordRequest) returns (WordResponse);  
  rpc Go(GoRequest) returns (GoResponse);  
}

service 由 service 字段定义, 后面紧跟需要定义的服务名称。service 由若干个调用组成,每个调用由 rpc 调用名称(调用参数) returns (返回参数) 组成,其中参数为 message 定义的消息。

1.5 生成 GO 文件

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld.proto

--go_out=.--go-grpc_out=. 分别指明 go 和 go-grpc 文件生成路径。

2 Grpc

2.1 (srv)注册 Grpc 服务

lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8080))  
if err != nil {  
   zap.S().Infof("failed to listen: %v", err)  
}

zap.S().Infof("server listening at %v", lis.Addr())  
if err := s.Serve(lis); err != nil {  
   zap.S().Infof("failed to serve: %v", err)  
}

2.2 (cli)请求 Grpc 服务

func client() {  
   conn, err := net.Dial("tcp", "localhost:8080")  
   if err != nil {  
      fmt.Println("Error: ", err)  
      return  
   }  
   reply := ""  
   args := fmt.Sprintf("Goodbye %d", n)  
   client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))  
   err = client.Call("hello.Hello", args, &reply)  
   if err != nil {  
      fmt.Println("Error: ", err)  
      return  
   }  
   fmt.Println("Reply: ", reply)  
   return  
}  

2.3 健康检查/心跳检测

healthcheck := health.NewServer() // 注册健康检查  
healthgrpc.RegisterHealthServer(s, healthcheck)

go func() {  
   next := healthpb.HealthCheckResponse_SERVING  
  
   for {  
      healthcheck.SetServingStatus("user", next)  
  
      if next == healthpb.HealthCheckResponse_SERVING {  
         next = healthpb.HealthCheckResponse_NOT_SERVING  
      } else {  
         next = healthpb.HealthCheckResponse_SERVING  
      }  
  
      time.Sleep(1 * time.Second)  
   }  
}()