grpc-python介绍及使用

gRPC是什么

所谓RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从server/client模型。使用的时候客户端调用server端提供的接口就像是调用本地的函数一样。如下图所示就是一个典型的RPC结构图。

在这里插入图片描述
gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持。

使用场景

  1. 低延时、高可用的分布式系统;
  2. 移动端与云服务端的通讯;
  3. 使用protobuf,独立于语言的协议,支持多语言之间的通讯;
  4. 可以分层扩展,如:身份验证,负载均衡,日志记录,监控等;

gRPC 与 RESTful API

特性 gRPC RESTful API
规范 必须.proto 可选 OpenAPI
协议 HTTP/2 任意版本的 HTTP 协议
有效载荷 Protobuf(小、二进制) JSON(大、易读)
浏览器支持 否(需要 grpc-web)
流传输 客户端、服务端、双向 客户端、服务端
代码生成 OpenAPI + 第三方工具

模块安装

pip install grpcio-tools
pip install grpc

gRPC 使用实例

gRPC的使用通常包括如下几个步骤:

  1. 通过protobuf来定义接口和数据类型
  2. 编写gRPC server端代码
  3. 编写gRPC client端代码

下面来通过一个实例来详细讲解上述的三步。 下边的hello world实例完成之后,其目录结果如下:
在这里插入图片描述

定义接口和数据类型

通过protobuf定义接口和数据类型

syntax = "proto3";

package rpc_package;

// define a service
service HelloWorldService {
    
    
    // define the interface and data type
    rpc SayHello (HelloRequest) returns (HelloReply) {
    
    }
}

// define the data type of request
message HelloRequest {
    
    
    string name = 1;
}

// define the data type of response
message HelloReply {
    
    
    string message = 1;
}

使用gRPC protobuf生成工具生成对应语言的库函数

python -m grpc_tools.protoc -I=./protos --python_out=./rpc_package --grpc_python_out=./rpc_package ./protos/user_info.proto

这个指令会自动生成rpc_package文件夹中的helloworld_pb2.py和helloworld_pb2_grpc.py,但是不会自动生成__init__.py文件,需要我们手动添加。

gRPC server端代码

#!/usr/bin/env python
# -*-coding: utf-8 -*-

from concurrent import futures
import grpc
import logging
import time

from rpc_package.helloworld_pb2_grpc import add_HelloWorldServiceServicer_to_server, \ 
    HelloWorldServiceServicer
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply


class Hello(HelloWorldServiceServicer):

    # 这里实现我们定义的接口
    def SayHello(self, request, context):
        return HelloReply(message='Hello, %s!' % request.name)


def serve():
    # 这里通过thread pool来并发处理server的任务
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    # 将对应的任务处理函数添加到rpc server中
    add_HelloWorldServiceServicer_to_server(Hello(), server)

    # 这里使用的非安全接口,世界gRPC支持TLS/SSL安全连接,以及各种鉴权机制
    server.add_insecure_port('[::]:50000')
    server.start()
    try:
        while True:
            time.sleep(60 * 60 * 24)
    except KeyboardInterrupt:
        server.stop(0)


if __name__ == "__main__":
    logging.basicConfig()
    serve()

gRPC client端代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
import logging

import grpc
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply
from rpc_package.helloworld_pb2_grpc import HelloWorldServiceStub

def run():
    # 使用with语法保证channel自动close
    with grpc.insecure_channel('localhost:50000') as channel:
        # 客户端通过stub来实现rpc通信
        stub = HelloWorldServiceStub(channel)

        # 客户端必须使用定义好的类型,这里是HelloRequest类型
        response = stub.SayHello(HelloRequest(name='eric'))
    print ("hello client received: " + response.message)

if __name__ == "__main__":
    logging.basicConfig()
    run()

执行·
1.先执行server端代码

python hello_server.py

2.接着执行client端代码如下:

➜  grpc_test python hello_client.py
hello client received: Hello, eric!

猜你喜欢

转载自blog.csdn.net/qq_45066628/article/details/118602349