我正在参加「启航计划」

前语

最近在看有关微服务的内容,今日想总结一下有关gRPC的常识.下面的图很好的解说了gRPC的特点,服务端负责完成接口来处理客户端的请求,客户端直接调用需求的服务就行.最杰出的特点便是gRPC的服务端和客户端能够支撑不同言语完成,也便是说不再有言语的障碍会啥用啥就好了(像其它一些RPC结构比如Dubbo就只支撑Java而不能跨言语通讯)

gRPC 初识

1. gRPC与ProtoBuf

假如对gRPC不熟悉能够先去看看gRPC官网的介绍

默许情况下,gRPC是使用Protocol Buffers来传递数据的,比起xml或许json更加轻量(二进制格局而不是文本格局).在这儿关于ProtoBuf和gRPC的装置配置我就不多赘述,能够参考其他博客.

惯例的步骤也很简单,根据官网的教程首要使用protobuf界说好服务,然后使用protoc生成各自言语的proto文件进行调用完成不同言语的服务端与客户端.

2. gRPC的适用场景

  • 散布式: gRPC的低延迟和高吞吐非常合适散布式微服务
  • 多言语开发: gRPC支撑多种言语,因而合适不同言语的工程师们混合开发
  • 轻量化音讯: gRPC发送的音讯是ProtoBuf二进制,比普通的二进制格局音讯有天然优势

3. Demo

我平时常用的几种言语便是C++ Go Python,不过假如做服务用C++还是比较少的,所以今日测验一下用GoPython别离写服务端和客户端进行通讯.

3.1 Proto界说及转化

syntax="proto3";
​
option go_package="./;hello";
​
package hello;
​
service Greeter{
 rpc SayHello(HelloRequest) returns (HelloReply){}
}
​
message HelloRequest{
 string name = 1;
}
​
message HelloReply{
 string message = 1;
}

这儿界说了Greeter这个服务以及服务中传递的音讯,接下来需求转化为两种言语的代码

  • Go

protoc --proto_path=../protos --go_out=plugins=grpc:. hello.proto

protoc --proto_path=../protos --go_out=. --go-grpc_out=. hello.proto

  • Python

pip install grpcio grpcio-tools

python -m grpc_tools.protoc -I ./protos --python_out=. --pyi_out=. --grpc_python_out=. ./protos/hello.proto

3.2 服务端部分Go完成

package main
​
import (
    pb "PRC_learning/hello"
    "context"
    "flag"
    "fmt"
    "google.golang.org/grpc"
    "log"
    "net"
)
​
type server struct{ pb.UnimplementedGreeterServer }
​
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}
​
var port = flag.Int("port", 50001, "The Server Port")
​
func main() {
    flag.Parse()
    lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
    if err != nil {
        log.Fatal("fail to listen :%v", err)
    }
​
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    log.Printf("server listening at %v", lis.Addr())
    if err := s.Serve(lis); err != nil {
        log.Fatalf("fail to serve:%v", err)
    }
}
​

flag能够经过命令行解析设置服务的端口号,这儿ip我设置的是本地.这儿服务主要是完成hello_grpc.pb.go中的接口

gRPC 初识

3.3 客户端部分Python完成

import grpc
import hello_pb2
import hello_pb2_grpc
​
​
def run():
  with grpc.insecure_channel(target='localhost:50001',
                options=[
                  ('grpc.lb_policy_name','pick_first'),
                  ('grpc.enable_retries',0),
                  ('grpc.keepalive_timeout_ms',1000)
                ]) as channel:
    stub=hello_pb2_grpc.GreeterStub(channel)
    response=stub.SayHello(hello_pb2.HelloRequest(name='xxx'),timeout=10)
  print(f"Greeter client received:{response.message}")
​
if __name__ == '__main__':
  run()

gRPC 初识

关注于run函数部分,除了为了通讯设置相同的端口,更应该注意到SayHello这个办法.这个Demo是一元的音讯(还有流式的音讯等方式)所以对应unary_unary这个办法

gRPC 初识

需求传入某个办法,请求的编码序列化以及回应的解序列化.上面那张图就完成了这三个参数

gRPC 初识

最终返回呼应,输出呼应值中的信息就完成了一次通讯

3.4 运转

首要运转服务端 go run server.go

gRPC 初识

然后运转客户端 python client.py

gRPC 初识