grpc
gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持. grpc/grpc The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#) - grpc/grpc
Protocol Buffer
其实 是 Google出品的一种轻量 & 高效的结构化数据存储格式,性能比 Json、XML 真的强!太!多! protobuf经历了protobuf2和protobuf3,pb3比pb2简化了很多,目前主流的版本是pb3
优点上
- 体积更小,序列化和传输的速度更快
- 使用相对简单维护成本低兼容性好
- 跨平台,跨语言
缺点上
- 二进制存储,自释性差
- XML和Json当道,通用性较差
基于以上特点,我们可以看到在传输数据量较大的需求场景下,Protobuf比XML、Json 更小、更快、使用和维护更简单!
syntax = "proto3";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name = 1;
}
message HelloReply{
string message = 1;
}
Python使用grpc
# 安装grpc与grpc-tools
pip install grpcio -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install grpcio-tools -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
# 生成python的protobuf文件
python3 -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. hello.proto
# server
import grpc
from concurrent import futures
from proto.hello_pb2 import HelloReply
from proto.hello_pb2_grpc import GreeterServicer,add_GreeterServicer_to_server
class Greeter(GreeterServicer):
def SayHello(self, request, context):
return HelloReply(message=f"你好,{request.name}")
if __name__ == "__main__":
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port("0.0.0.0:12345")
server.start()
server.wait_for_termination()
# client
import grpc
from proto import hello_pb2, hello_pb2_grpc
if __name__ == "__main__":
with grpc.insecure_channel("localhost:12345") as chan:
stub = hello_pb2_grpc.GreeterStub(chan)
rsp = stub.SayHello(hello_pb2.HelloRequest(name="zj"))
print(rsp.message)
Go语言使用grpc
安装用于生成gRPC服务代码的协议编译器
下载地址:https://github.com/google/protobuf/releases
go install google.golang.org/grpc@latest
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
syntax = "proto3";
option go_package = ".;proto";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name = 1;
}
message HelloReply{
string message = 1;
}
// protoc -I . hello.proto --go_out=plugins=grpc:.
// protoc -I . hello.proto --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:.
// server
package main
import (
"context"
"google.golang.org/grpc"
"net"
"test/day06/proto"
)
type Server struct {
}
func (s *Server) SayHello(ctx context.Context, req *proto.HelloRequest) (*proto.HelloReply, error) {
return &proto.HelloReply{Message: "hello" + req.Name}, nil
}
func main() {
g := grpc.NewServer()
proto.RegisterGreeterServer(g, &Server{})
lis, err := net.Listen("tcp", "0.0.0.0:12345")
if err != nil {
panic("failed to listen:" + err.Error())
}
err = g.Serve(lis)
if err != nil {
panic("failed to listen:" + err.Error())
}
}
// client
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"test/day06/proto"
)
func main() {
conn, err := grpc.Dial(":12345", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic("failed to listen:" + err.Error())
}
defer conn.Close()
c := proto.NewGreeterClient(conn)
r, err := c.SayHello(context.Background(), &proto.HelloRequest{Name: " zj1007"})
if err != nil {
panic("failed to listen:" + err.Error())
}
fmt.Println(r.Message)
}