gRPC服务的编写

gRPC服务的编写

安装gRPC相关的库,grpcio-tools主要用根据我们的protocol buffer定义来生成Python代码,官方解释是Protobuf code generator for gRPC。protocolbuffers/protobuf是Google开发的一种序列化数据结构的协议。具体结构和语法超纲了,现在还不多用做太多理解,只要会用就行了

sudo pip3 install grpcio grpcio-tools

定义服务:使用protocolbuffers/protobuf格式来创建结构化数据文件SimpleCal.proto,内容如下:

syntax = "proto3";

service Cal {
rpc Add(AddRequest) returns (ResultReply) {}
rpc Multiply(MultiplyRequest) returns (ResultReply) {}
}

message AddRequest {
int32 number1 = 1;
int32 number2 = 2;
}

message MultiplyRequest {
int32 number1 = 1;
int32 number2 = 2;
}

message ResultReply {
int32 number = 1;
}

在SimpleCal.proto 文件中定义了一个服务Cal,定义了2个RPC方法:Add和Multiply,需要分别在gRPC的服务端中实现加法和乘法。

同时我们也定义了2个方法的参数,Add方法的参数是AddRequest,包含number1和number2两个整数参数。Multiply方法的参数是MultiplyRequest,里面也有number1和number2两个整数参数。两个函数的返回结构都是ResultReply,内容是一个整数。

根据上面的定义,生成Python代码:

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./SimpleCal.proto
dir

服务端代码:
# -*- coding: utf-8 -*-
from concurrent import futures
import grpc
import SimpleCal_pb2
import SimpleCal_pb2_grpc

class CalServicer(SimpleCal_pb2_grpc.CalServicer):
def Add(self, request, context): # Add函数的实现逻辑
print("Add function called")
return SimpleCal_pb2.ResultReply(number=request.number1 + request.number2)

def Multiply(self, request, context): # Multiply函数的实现逻辑
print("Multiply service called")
return SimpleCal_pb2.ResultReply(number=request.number1 * request.number2)

def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
SimpleCal_pb2_grpc.add_CalServicer_to_server(CalServicer(),server)
server.add_insecure_port("[::]:50051")
server.start()
print("grpc server start...")
server.wait_for_termination()

if __name__ == '__main__':
serve()


客户端代码:
# -*- coding: utf-8 -*-
import SimpleCal_pb2
import SimpleCal_pb2_grpc
import grpc

def run(n, m):
channel = grpc.insecure_channel('localhost:50051') # 连接上gRPC服务端
stub = SimpleCal_pb2_grpc.CalStub(channel)
response = stub.Add(SimpleCal_pb2.AddRequest(number1=n, number2=m)) # 执行计算命令
print(f"{n} + {m} = {response.number}")
response = stub.Multiply(SimpleCal_pb2.MultiplyRequest(number1=n, number2=m))
print(f"{n} * {m} = {response.number}")

if __name__ == "__main__":
run(100, 300)

 

使用Nginx来代理gRPC

gRPC是基于HTTP/2协议的,Nginx在1.9.5里开始支持HTTP/2,在1.13.10里开始支持gRPC。为了反向代理gRPC服务,编译Nginx的时候必须要添加这两个参数:--with-http_ssl_module --with-http_v2_module

给Nginx添加如下的server配置:

server {
listen 80 http2;

location / {
grpc_pass grpc://localhost:50051;
}
}

把这段server的配置添加到Nginx的http段里,配置和启动好Nginx之后,然后把cal_client.py里的channel = grpc.insecure_channel('localhost:50051') 一行的连接地址替换为Nginx提供的地址就可以了。执行结果是一样的,就不再做一遍了。

接着往下挖掘gRPC的HTTP2.0接口细节的话,可以打开SimpleCal_pb2_grpc.py你可以看到在CalStub这个类的__init__方法里,定义了Add和Multiply两个函数对应的uri。

class CalStub(object):
# missing associated documentation comment in .proto file
pass

def __init__(self, channel):
"""Constructor.

Args:
channel: A grpc.Channel.
"""
self.Add = channel.unary_unary(
'/Cal/Add', # 这个是对应Add方法的http url地址
request_serializer=SimpleCal__pb2.AddRequest.SerializeToString,
response_deserializer=SimpleCal__pb2.ResultReply.FromString,
)
self.Multiply = channel.unary_unary(
'/Cal/Multiply', # 这个是对应Multiply方法的http url地址
request_serializer=SimpleCal__pb2.MultiplyRequest.SerializeToString,
response_deserializer=SimpleCal__pb2.ResultReply.FromString,
)
查看Nginx的日志也能表明这一点:
127.0.0.1 - - [18/Nov/2019:20:09:25 +0800] "POST /Cal/Add HTTP/2.0" 200 8 "-" "grpc-python/1.25.0 grpc-c/8.0.0 (manylinux; chttp2; game)"
127.0.0.1 - - [18/Nov/2019:20:09:25 +0800] "POST /Cal/Multiply HTTP/2.0" 200 9 "-" "grpc-python/1.25.0 grpc-c/8.0.0 (manylinux; chttp2; game)"
如果部署了多个gRPC服务端,也可以使用Nginx的upstream来做多个后端的负载均衡。

 

https://www.jb51.net/javascript/32884640y.htm
npm install @grpc/grpc-js @grpc/proto-loader

 

https://zhuanlan.zhihu.com/p/501843416
安装go语言grpc包
go get -u google.golang.org/grpc

https://www.cnblogs.com/yanweifeng/p/17485496.html
因为目前的protoc编译器,默认没有包含go语言代码生成器,所以需要单独安装插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2


新版本的protoc使用grpc容易遇到的两个坑,gen gRPC,mustEmbedUnimplementedHelloServer
https://blog.csdn.net/neve_give_up_dan/article/details/126920398

php在windows使用grpc和protobuf入门(超详细)
https://blog.csdn.net/qq_31065757/article/details/129787461
https://github.com/lifenglsf/grpc_for_windows/tree/master

posted @ 2024-12-14 15:20  河北大学-徐小波  阅读(5)  评论(0编辑  收藏  举报