python-grpc的使用

在gRPC中,客户端应用程序可以直接在其他计算机上的服务器应用程序上调用方法,就好像它是本地对象一样,从而使您更轻松地创建分布式应用程序和服务。与许多RPC系统一样,gRPC围绕定义服务的思想,指定可通过其参数和返回类型远程调用的方法。在服务器端,服务器实现此接口并运行gRPC服务器以处理客户端调用。在客户端,客户端具有一个存根(在某些语言中仅称为客户端),提供与服务器相同的方法。

默认情况下,gRPC使用协议缓冲区,这是谷歌成熟的开源机制,用于序列化结构化数据(尽管它也可以用于其他数据格式,如JSON)。使用协议缓冲区时,第一步是为要在proto文件中序列化的数据定义结构:这是一个扩展名为.proto的普通文本文件。协议缓冲区数据结构为消息,其中每个消息都是包含一系列名为字段的名称-值对的信息的小逻辑记录。这里有一个简单的例子:

syntax = "proto3";

service Math{
    rpc add(Params) returns(Response){}
    rpc reduce(Params) returns(Response){}
}

message Params{
    int32 num1 = 1;
    int32 num2 = 2;
}

message Response{
    int32 result = 1;
}

grpc使用protobuf进行数据传输,protobuf是一种数据交换格式,由三部分组成:

  • proto文件:使用proto语法的文本文件,用来定义数据格式。proto语法现在有proto2与proto3两个版本,建议使用proto3
  • protoc:protobuf编译器将proto文件编译成不同的语言实现,这样不同语言中的数据就可以和protobuf格式的数据进行交互
  • protobuf运行时:protobuf运行时所需的库,和protoc编译生成的代码进行交互

四种服务方法

  • 一个简单的RPC,客户端使用存根将请求发送到服务器,然后等待响应返回,就像正常的函数调用一样
rpc get_feature(Params) returns(Response){}
  • 服务器(响应)流式RPC,客户端在其中向服务器发送请求,并获取流以读取一系列消息。客户端从返回的流中读取,直到没有更多的消息为止。
rpc get_feature(Params) returns(stream Response){}
  • 客户端(请求)流式RPC,客户端在其中编写一系列消息,然后再次使用提供的流将它们发送到服务器。客户端写完消息后,它将等待服务器读取消息并返回其响应
rpc get_feature(stream Params) returns(Response){}
  • 双向流式RPC,双方都是用读写流发送一系列消息。这两个流独立运行,因此客户端和服务器可以按照自己喜欢的顺序进行读写。服务器在读写响应之前等待接收所有客户端消息,或者可以先读取消息后写入消息。每个流的消息顺序都会保留
rpc get_feature(stream Params) returns(stream Response){}

安装

安装grpc与grpc工具包

pip3 install grpcio
pip3 install grpcio-tools

举个栗子

有这么一个文件math.proto,内容如下:

syntax = "proto3";

service Math{
    rpc add(Params) returns(Response){}
    rpc reduce(Params) returns(Response){}
}

message Params{
    int32 num1 = 1;
    int32 num2 = 2;
}

message Response{
    int32 result = 1;
}

编译.proto文件

/**
-I                  指定工作目录
--python_out        指定python文件目录
--grpc_python_out   指定grpc python文件目录
**/
python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./math.proto

执行上面的命令进行编译之后,会在当前目录生成math_pb2.pymath_pb2_grpc.py文件。服务端代码如下:

import grpc
from concurrent import futures

import math_pb2
import math_pb2_grpc

class MathServer(math_pb2_grpc.MathServicer):

    def add(self, request, context):
        return math_pb2.Response(result=request.num1 + request.num2)

    def reduce(self, request, content):
        return math_pb2.Response(result=request.num1 - request.num2)

if __name__ == '__main__':
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
    math_pb2_grpc.add_MathServicer_to_server(MathServer(), server)
    server.add_insecure_port("[::]:50001")
    server.start()
    print('server is starting...')
    server.wait_for_termination()

客户端代码如下:

import grpc

import math_pb2
import math_pb2_grpc

channel = grpc.insecure_channel("localhost:50001")
stub = math_pb2_grpc.MathStub(channel)
def add(num1, num2):
    response = stub.add(math_pb2.Params(num1=num1, num2=num2))
    print(f'response: {response.result}')

def reduce(num1, num2):
    response = stub.reduce(math_pb2.Params(num1=num1, num2=num2))
    print(f'response: {response.result}')

if __name__ == '__main__':
    add(1, 2)

导入其他proto文件

我们可以使用import指令来导入其他的proto文件。假设有这么两个文件types.protomath.prototypes.proto文件内容如下:

syntax = "proto3";
package types;

message Params{
    int32 num1 = 1;
    int32 num2 = 2;
}

message Response{
    int32 result = 1;
}

现在我们需要在math.proto文件中调用这个types.proto文件的内容。math.proto文件内容如下:

syntax = "proto3";

// protos/types.proto表示在protos文件夹下面的types.proto文件
import "protos/types.proto";

service Math{
    // types为types.proto文件中的package名称
    rpc add(types.Params) returns(types.Response){}
    rpc reduce(types.Params) returns(types.Response){}
}

更多grpc的使用:https://www.grpc.io/docs/

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本门课程是带大家进入微服务领域入门的课程,很适合新手小白学习的课程。1: 什么是rpc?RPC(Remote Procedure Call)是函数对函数的远程调用,传输协议tcp,http,主要是基于xml,json序列化协议(这里的序列化协议是对数据编解码的方式),项目中我们真正用到的是grpcgrpc是一个框架,基于http2.0的长链接,性能有所改进,重要的是grpc用的是Google开源的protobuf序列化协议,它比json,xml性能更快,在压缩数据方面也更小。总之我们选择grpc最主要的有两点:1:支持跨语言开发(如python,golang,java)2:  grpc首先是一个框架,封装rpc,让程序员只关注代码逻辑即可 2: 为什么用grpc,而不用flask,django,tornado,即http协议?1:http的调用是根据url的(即restful),它跟rpc的调用最大的区别就是这里,rpc的调用,你就像调用一个本地函数一样简单,而且微服务,分布式也是从rpc开始的,学好rpc对以后做好分布式会更有帮助,其实go语言和python语言里都有rpc(如xmlrpc,jsonrpc,zerorpc),我们之所以学习go语言里的rpc是因为go语言的rpc相对更加灵活,go语言本身也支持高并发,这一点对于分布式来说更好。2:其次http协议,用过flask框架的人都知道,请求一次数据后就断开,而grpc基于http2.0,它不但可以保持长链接,传输效率也更高,使用方面,因为http2.0相当于tcp一样使用,现在很多大厂也都开始用http2.0了。http2.0相比http的优势很明显,头部压缩,分流,针对tcp的多路复用。所以基于http2.0的grpc无论从生态和性能方面都更好。 这张图是一个gRPC相关的架构图,同学们可以通过这张图了解gRPC在项目中的使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值