rpc, gRPC quick start, python call, protobuf protocol

What is rpc? What is grpc?

What is RPC


Remote Procedure Call Protocol RPC (Remote Procedure Call Protocol)
RPC refers to remote procedure call, that is to say, two servers A and B, an application deployed on server A, wants to call the function/method provided by the application on server B, because It is not in the same memory space and cannot be called directly. It needs to express the semantics of the call and convey the data of the call through the network.
For example: in service a, call the get method in the ticket service of service b, then call b directly in service a. ticket.get() to call directly

Without knowing the details of the call, the client calls an object that exists on the remote computer, just like calling an object in the local application.

what is grpc


gRPC (Google Remote Procedure Call) is a high-performance, general-purpose open source RPC framework. It is designed by Google mainly for mobile application development and based on the HTTP/2 protocol standard. It is developed based on the ProtoBuf (Protocol Buffers) serialization protocol and supports many Development languages ​​(python, golang, javascript, C, C++, Node.js, Ruby, Objective-C, PHP and C#, etc.).
gRPC provides an easy way to precisely define services and automatically generate a library of highly reliable client functions for iOS, Android, and backend services . The client takes full advantage of advanced streaming and linking features, which help save bandwidth, reduce the number of TCP connections, save CPU usage, and battery life.

RESTful gRPC
Full Name REpresentational State Transfer Google Remote Procedure Call
Payload Readable Data (typically JSON) Unreadable Binary Data (Protobuf)
HTTP HTTP 1.1/HTTP 2 HTTP/2
Performance Slower Faster
Type Safety No Yes
Cross Language Yes Yes
Client Setup Required Not required
Supported Functions GET/PUT/DELETE/POST/... Any function

// Client side 
// Student student = Call(ServerAddr, addAge, student)
1. Map this call to Call ID.
2. Serialize the Call ID, student (params), and pack it in binary form
3. Send the data packet obtained in 2 to ServerAddr, which needs to use the network transport layer
4. Wait for the server to return the result
5. If the server call is successful, then Deserialize the result and assign it to the student, and update the age

// Server side
1. Maintain a mapping call_id_map from Call ID to function pointer locally, you can use Map<String, Method> callIdMap
2. Wait for client request
3. After getting a request, deserialize its data packet to get Call ID
4. Find the corresponding function pointer by searching in callIdMap
5. After deserializing the student (params), call the addAge() function locally to get the result
6. Serialize the student result and return it to the Client through the network

what is protobuf


protobuf (Google Protocol Buffers) is an efficient protocol data exchange format tool library (similar to Json) provided by Google, but compared to Json, Protobuf has higher conversion efficiency, time efficiency and space efficiency are 3-5 of JSON Double
is cross-language: python golang java c++ javascript and so on


Generate python client and server

install dependencies

安装依赖:
pip install grpcio
pip install grpcio-tools
pip install protobuf
转化proto文件成client和server
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. wenet.proto
// 文件名 hello.proto,proto版本
syntax = "proto3";

package hello;

// 定义服务
service Greeter {
  // 发送数据
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// 请求消息,包含用户的姓名。
message HelloRequest {
  string name = 1;
  string age = 2;
  string note=3;
}

// 响应消息,包含问候语。
message HelloReply {
  string message = 1;
}

Enter at the command line:

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

gRPC client (client.py):

import grpc  # 导入gRPC库
import hello_pb2  # 导入生成的proto文件中的消息类型
import hello_pb2_grpc  # 导入生成的proto文件中的服务类型

def run():
    channel = grpc.insecure_channel('localhost:50051')  # 创建与服务器的通信通道,参数为服务器的地址和端口
    stub = hello_pb2_grpc.GreeterStub(channel)  # 创建与服务器的Stub对象,参数为通信通道
    response = stub.SayHello(hello_pb2.HelloRequest(name='John', age='25', note='Hello gRPC'))  # 调用服务器上的方法,参数为请求消息对象
    print("Response received from server: " + response.message)  # 打印服务器返回的响应消息

if __name__ == '__main__':
    run()  # 运行客户端代码

gRPC server (server.py):

import grpc  # 导入gRPC库
from concurrent import futures  # 导入concurrent.futures库,用于多线程处理
import hello_pb2  # 导入生成的proto文件中的消息类型
import hello_pb2_grpc  # 导入生成的proto文件中的服务类型

class GreeterServicer(hello_pb2_grpc.GreeterServicer):
    def SayHello(self, request, context):  # 实现proto文件中定义的方法,参数为请求消息对象和上下文对象
        message = 'Hello, ' + request.name + '! You are ' + request.age + ' years old.'  # 构造响应消息
        return hello_pb2.HelloReply(message=message)  # 返回响应消息对象

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))  # 创建gRPC服务器对象,参数为线程池的最大工作线程数
    hello_pb2_grpc.add_GreeterServicer_to_server(GreeterServicer(), server)  # 将服务实现添加到服务器中,参数为服务实现对象和服务器对象
    server.add_insecure_port('[::]:50051')  # 指定服务器监听的地址和端口,参数为地址和端口
    server.start()  # 启动服务器
    print("Server started. Listening on port 50051.")  # 打印服务器启动信息
    server.wait_for_termination()  # 等待服务器终止

if __name__ == '__main__':
    serve()  # 运行服务器代码

Commonly used protobuf data types and pb files

Commonly used protobuf data types

.proto Type Notes C++ Type Java Type Python Type[2] Go Type Ruby Type
double double double float float64 Float
float float float float float32 Float
int32 Using variable length encoding is very inefficient for negative values. If your domain may have negative values, please use sint64 instead int32 int int int32 Fixnum or Bignum (as needed)
uint32 Use variable length encoding uint32 int int uint32 Fixnum or Bignum (as needed)
uint64 Use variable length encoding uint64 long int uint64 Bignum
sint32 Use variable-length encodings, which are much more efficient than int32 for negative values int32 int int int32 Fixnum or Bignum (as needed)
sint64 Signed integer value using variable length encoding. More efficient than usual int64 when encoding. int64 long int int64 Bignum
fixed32 Always 4 bytes, this type is more efficient than uint32 if the value is always greater than 228. uint32 int int uint32 Fixnum or Bignum (as needed)
fixed64 Always 8 bytes, this type is more efficient than uint64 if the value is always greater than 256. uint64 long int uint64 Bignum
sfixed32 always 4 bytes int32 int int int32 Fixnum or Bignum (as needed)
sfixed64 always 8 bytes int64 long int int64 Bignum
bool bool boolean bool bool TrueClass/FalseClass
string A string must be UTF-8 encoded or 7-bit ASCII encoded text. string String str/unicode string String (UTF-8)
bytes May contain byte data in any order. string ByteString str/b'' []byte

String (ASCII-8BIT)

repeated array(list) RepeatedField<type> list []type RepeatedField
map dictionary Map<key_type, value_type> dict {} Map

References: grpc-python02--understand rpc and grpc and create a simple grpc-python_哔哩哔哩_bilibili

gRPC (1) Introduction: What is RPC? | Go Tech Forum

https://www.youtube.com/watch?v=gnchfOojMk4

A simple example of one of the python grpc framework_51CTO Blog_python web framework

Getting Started with Python gRPC - Nuggets

Guess you like

Origin blog.csdn.net/m0_61634551/article/details/131647279