tags: Advanced knowledge of Python python Programming language rpc Microservice grpc
What is RPC service
RPC, is the abbreviation of Remote Procedure Call, translated into Chinese means remote procedure call. RPC is a service that allows a program to call a class method or function in another address space (usually on another machine).
It is a technology that is built on a computer network and hides the underlying network. It can call remote programs like local services, and improve throughput without high coding costs.
Why use RPC service
With the rapid development of computer technology, a single machine running service solution is no longer sufficient to support more and more network request loads. Distributed solutions are beginning to emerge, and a business scenario can be dismantled. Run on multiple machines, and each machine only completes one or a few business modules. In order to allow other machines to use the business module methods in a certain machine, there is an RPC service, which is a service based on a protocol that specifically implements remote method calls. Nowadays, many mainstream languages support RPC services, commonly used are Dubbo of Java, net/rpc & RPCX of Go, and gRPC of Google.
About gRPC
Most RPCs are implemented based on sockets, which can be more efficient than http requests. gRPC is a high-performance framework for RPC services developed and open sourced by Google. It is based on the http2.0 protocol and currently supports C, C++, Java, Node.js, Python, Ruby, Objective-C, PHP and C# Wait language. To transfer method calls, call parameters, response parameters, etc. between the two servers, these parameters need to be serialized. gRPC uses the protocol buffer syntax (check proto), and the proto syntax can define what to call Methods, parameters, and response formats can easily complete remote method calls, and are very helpful for expanding and updating parameters.

Before using gRPC to implement remote method calls, we need to understand the protocol buffer syntax, install tools that support protocol buffer syntax to be compiled into .proto files, and then complete the gRPC server (remote method provider) and client (caller) construction And packaging.
Protocol Buffer is Google's cross-language, cross-platform, and extensible mechanism for serializing structured data-a data format that is smaller, faster, and simpler than XML. You can define the structure of the data, such as method names, parameters, and response formats, and then you can use the source code generated by the corresponding language tools to easily write and read structured data in various languages in various data streams.
package test;
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
The above example is a .proto file. The first line of the file specifies the package name so that you can import the definition of this file in other proto files. The second line is that you are using proto3 syntax: if you don’t do this, protobuf The compiler will assume that you are using proto2. This must be the first non-empty non-comment line of the file. Currently, proto3 syntax is recommended.
SearchRequest is the name of the message body. It specifies three fields, which respectively specify the type and order of the fields. The order must start from 1, and cannot be repeated;
Singular (default): A well-formed message can contain zero or one (but no more than one) in this field.
repeated: This field can be repeated any number of times (including zero) in a well-formed message. The order of repeated values will be preserved. E.g:
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
repeated Body body = 4;
}
message Body {
int32 id = 1;
string number = 2;
}
The above example actually defines a format, which is expressed in our usual json format:
{
"query": str,
"page_number":int,
"result_per_page":int,
"body":[
{
"id":int,
"number":str
}
],
}
| .proto Type | Remarks | Python Typ |
|---|---|---|
| double | float | |
| float | float | |
| int32 | Using variable length coding is very inefficient for negative values. If your domain may have negative values, please use sint64 instead | int |
| uint32 | Use variable length encoding | int/long |
| uint64 | Use variable length encoding | int/long |
| sint32 | Use variable length coding, these codes are much more efficient than int32 when negative values | int |
| sint64 | Use variable length encoding, signed integer value. Encoding is more efficient than the usual int64. | int/long |
| fixed32 | It is always 4 bytes. If the value is always greater than 228, this type will be more efficient than uint32. | int |
| fixed64 | Always 8 bytes, if the value is always greater than 256, this type will be more efficient than uint64. | int/long |
| sfixed32 | Always 4 bytes | int |
| sfixed64 | Always 8 bytes | int/long |
| bool | Boolean value | bool |
| string | A string must be UTF-8 encoded or 7-bit ASCII encoded text. | str/unicode |
| bytes | May contain byte data in any order. | str |
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
Corpus corpus = 4;
}
The first constant of the Corpus enumeration is mapped to zero: each enumeration definition must contain a constant mapped to zero as its first element. This is because:
service SearchService {
rpc Search(SearchRequest)returns(SearchResponse);
}
The above statement defines the method name Search for remote invocation. After the source code of the corresponding language is compiled, remote invocation can be used, for exampleInitialize the SearchService method in Python, then execute the Search method, which is to use the SearchRequest format to call the remote machine method, and then return the calling result in the defined SearchResponse format. According to the grammar definition of proto, it is even possible to implement cross-platform and cross-language remote calls.

According to actual work needs, to generate the custom message type Java, Python, C++, Go, Ruby, Objective-C, or C# .proto files in the following corresponding languages, you need to run .proto on the protobuf compiler protoc. If you have not installed the compiler, download the package and follow the instructions in the readme file.
Protobuf compiler is called as follows:
protoc --proto_path = IMPORT_PATH --cpp_out = DST_DIR --java_out = DST_DIR --python_out = DST_DIR --go_out = DST_DIR --ruby_out = DST_DIR --objc_out = DST_DIR --csharp_out = DST_DIR path / to / file .proto
Python generates the corresponding source code
sudo python -m pip install grpcio
python -m pip install grpcio-tools
# Compile proto file
python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. test.proto
python -m grpc_tools.protoc: The protoc compiler under python is implemented by the python module (module), so this step is very worry-free
--python_out=.: Compile and generate the path of protobuf-related code, here is generated to the current directory
--grpc_python_out=.: Compile and generate the path of grpc-related code, generated here to the current directory
-I. test.proto: The path of the proto file, where the proto file is in the current directory
Source code generated after compilation:
After generating the gRPC class that python can directly instantiate and call, we can start to build the RPC server (remote call provider) and client (caller).
from concurrent import futures
import time
import grpc
import test_pb2
import test_pb2_grpc
# Implement the SearchService defined in the proto file
class RequestRpc(test_pb2_grpc.SearchService):
# Implement the rpc call defined in the proto file
def doRequest(self, request, context):
return test_pb2.Search(query ='hello {msg}'.format(msg = request.name)) # The returned data is in accordance with the defined SearchResponse format
def serve():
# Start the rpc service, where you can define the maximum receiving and sending size (unit M), the default is only 4M
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), options=[
('grpc.max_send_message_length', 100 * 1024 * 1024),
('grpc.max_receive_message_length', 100 * 1024 * 1024)])
test_pb2_grpc.add_SearchServiceServicer_to_server(RequestRpc(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(60*60*24) # one day in seconds
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
def run():
# Connect to rpc server
channel = grpc.insecure_channel('localhost:50051')
# Invoke rpc service
stub = test_pb2_grpc.SearchServiceStub(channel)
response = stub.doRequest(test_pb2.SearchRequest(query='henry'))
print("client received: ", response)
if __name__ == '__main__':
run()
gRPC messages are serialized using protobuf, an effective binary message format. Protobuf serialization is very fast on the server and client. Protobuf serialized messages are small in size and can be loaded effectively, which is very important in limited bandwidth scenarios such as mobile applications.
gRPC is designed for HTTP/2. It is a major version of HTTP and has significant performance advantages compared to HTTP 1.x:
All gRPC frameworks provide first-class support for code generation. The core file of gRPC development is *.proto file, which defines the conventions of gRPC services and messages. According to this file, the gRPC framework will generate service base classes, messages and complete client code.
By sharing *.proto files between the server and the client, messages and client code can be generated from end to end. Client-side code generation eliminates duplicate messages on the client and server, and creates a strongly typed client for you. No need to write client code, which can save a lot of development time in applications with many services.
There is no formal specification of HTTP API with JSON. Developers do not need to discuss the best format for URLs, HTTP verbs and response codes. (Think about it, is it better to use Post or Get? Is it better to use Get or Put? When you think of a choice phobia, do you get entangled again and waste a lot of time)
The gRPC specification stipulates the format that the gRPC service must follow. gRPC eliminates disputes and saves developers time, because gPRC is consistent across platforms and implementations.
HTTP/2 provides the basis for long-term real-time communication streams. gRPC provides first-class support for streaming media via HTTP/2.
The gRPC service supports all stream combinations:
The deadline and cancellation of sub-gRPC calls help to enforce resource usage restrictions.
grpc-gateway reads the gRPC service definition and generates a reverse proxy server,Convert RESTful JSON API to RPC API Suppose you want to use Rpc as the internal API communication,At the same time, ...
protobuf installation protoc go plugin Code generation use When the message is encoded into a binary message body, the field number 1-15 will occupy 1 byte, and 16-2047 will occupy two bytes. So in so...
GRPC is a language neutral, platform neutral, open source RPC system developed by Google In GRPC, client applications can directly call another different machine on the server application of different...
brief introduction Reading harvest Define the server through the .proto file Generate the server and client code through the Protocol Buffer Use the Python GRPC interface to complete simple clients an...
Advanced use of RabbitMQ basic tutorial Related blog posts, recommended to view: RabbitMq basic tutorial installation and testing Basic concepts of RabbitMq basic tutorial Basic use of RabbitMQ basic ...
protocol buffers: Basics tutorial | Java | gRPC 1. Packing path configuration: 2. GRPC request and return: simple rpc server-side streaming client-side streaming se...
Interface implementation: Simple RPC: The client initiates the Point request, the server returns the Feature Message The entire interface request response process: 1. Execute the response process: onn...
Article catalog Grpc-python introduction Comparison of GRPC and RESTful What is Protobuf? Environmental preparation Module installation 1. Create a Proto file, and the parameter details 2. File compil...
python grpc learning environment helloworld.proto server client Compile the Proto file Reference article environment helloworld.proto server helloworld_grpc_server.py client helloworld_grpc_client.py ...
grpc use of python and golang In a Proto First define data.proto file Wherein DoFormat, actionrequest actionresponse define a plurality of data types may be defined similarly In addition there string ...