[Python advanced learning] basic use of gRPC tutorial

tags: Advanced knowledge of Python  python  Programming language  rpc  Microservice  grpc

Preface

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.

Get started quickly with gRPC

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.

Understand protocol buffer

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.

Grammar use

  1. Define the message type
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;

  1. Specify field rules
    The message field can be one of the following:

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
        }
    ],
}
  1. Scalar value type
    The scalar message field can have one of the following types-the table shows the type specified in the .proto file and the corresponding type in the automatically generated class:
.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
  1. Defaults
    When parsing a message, if the encoded message does not contain a specific singular element, the corresponding field in the parsing object will be set to the default value of the field. These default values ​​are type-specific:
  • For strings, the default value is an empty string.
  • For bytes, the default value is a null byte.
  • For bools, the default value is false.
  • For numeric types, the default value is zero.
  • For enumerations, the default value is the first defined enumeration value, which must be 0.
  • The default value of the repeated field is empty (usually an empty list for the corresponding language)
  1. Enumerated type
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:

  • There must be a zero value so that we can use 0 as the numeric default value.
  • The zero value must be the first element in order to be compatible with proto2 semantics, where the first enumerated value is always the default value.
  1. Definition method
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.

Use tools to generate source code for the corresponding language

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

  1. Install Python's gRPC source package grpcio, which is used to execute various underlying protocols and request response methods of gRPC
  2. Install the tool grpcio-tools for Python source code generation based on gRPC-based proto
sudo python -m pip install grpcio

python -m pip install grpcio-tools
  1. Perform compilation to generate python's proto serialization protocol source code:
# 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:

  • test_pb2.py: used to interact with protobuf data, this is a pythonized data structure file generated according to the data structure type defined by the proto file
  • test_pb2_grpc.py: used to interact with grpc, this is the class that defines the rpc method, including the request parameters and responses of the class, etc., which can be directly instantiated and called by python

Build Python gRPC service

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).

  1. Build server server.py
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()
  1. Build the client client.py
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()

Best Practices

  1. When writing proto files, pay attention to the definition of the data format, and consider scalability. For example, you can define api_version to distinguish between versions to prevent future versions from being compatible when large data formats are updated;
  2. For immutable types, it is recommended to use enumerations. For example, when requesting a field type and the value is fixed, you can use enumeration types;
  3. For the writing of server and client, it is recommended to specify the maximum receiving and sending size to avoid data overflow exception;
  4. gRPC occasionally will be disconnected and reconnected, so an exception handling mechanism should be added to catch the problem of remote call failure caused by reconnection, and then you can perform a retry (will be explained in detail in the next article);
  5. gRPC can use SSL or TLS protocol to realize http2.0 encrypted transmission and improve the security of the system (will be explained in detail in the next article);
  6. For services with large traffic and concurrency, some applications or components of microservices (such as istio) can be used to achieve traffic fusing, current limiting, etc., to improve stability.

Advantages of gRPC

performance

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:

  • Binary framework and compression. The HTTP/2 protocol is compact and efficient in sending and receiving.
  • Multiple HTTP/2 calls are multiplexed through a single TCP connection. Multiplexing eliminates end-of-line blocking.

Code generation

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.

Strict specification

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.

flow

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:

  • One yuan (no streaming)
  • Server to client flow
  • Client to server flow
  • Two-way streaming
    Deadline/timeout and cancellation
    gRPC allows clients to specify how long they are willing to wait for the RPC to complete. The deadline is sent to the server, and the server can decide what action to take when the deadline is exceeded. For example, the server may cancel an ongoing gRPC/HTTP/database request when it times out.

The deadline and cancellation of sub-gRPC calls help to enforce resource usage restrictions.

Recommended scenarios for using gRPC

  • Microservices-gRPC is designed for low latency and high throughput communication. gRPC is very suitable for lightweight microservices where efficiency is critical.
    Point-to-point real-time communication-gRPC provides excellent support for two-way streaming media. The gRPC service can push messages in real time without polling.
    Multi-language mixed development environment-gRPC tools support all popular development languages, making gRPC an ideal choice for multi-language development environments.
  • Network restricted environment-Use Protobuf (a lightweight message format) to serialize gRPC messages. The gRPC message is always smaller than the equivalent JSON message.

references

  1. https://juejin.im/post/5bb597c2e51d450e6e03e42d
  2. https://doc.oschina.net/grpc?t=58008
  3. https://juejin.im/post/5c86148ce51d45206776864e
  4. https://www.jianshu.com/p/43fdfeb105ff

Intelligent Recommendation

Basic use of grpc-gateway

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, ...

Basic use of grpc

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 Basic use

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...

Python-GRPC Basic Manual

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

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 ...

More Recommendation

Protocol-Buffers of GRPC basic tutorial

protocol buffers: Basics tutorial | Java | gRPC 1. Packing path configuration: 2. GRPC request and return:  simple rpc  server-side streaming   client-side streaming   se...

GRPC basic tutorial service creation

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...

GRPC-Python learning

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

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

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 ...

Copyright  DMCA © 2018-2026 - All Rights Reserved - www.programmersought.com  User Notice

Top