gRPC Python 教程(一): 原理与基本用法

前言
我们熟知的 REST通常只是用来进行数据的CRUD操作,可惜现实中,需要远程通信的应用场景远不止CRUD,很多场景还需要双向通信,或者要求高实时性,REST根本无法应付;用socket低阶函数方式编程难度大而且后期维护扩展困难。gRPC是适用于网络通信、接口编程的1个非常好的选项。

第1步学习目标:

  1. gRPC工作原理
  2. gRPC有哪些值得了解的优点
  3. 基本用法代码实现

gRPC工作原理

在介绍gRPC工作原理之前,先回顾一下什么是Remote Procedure Calls(RPC) 远程过程调用?
RPC令是客户机-服务器通信形式的一种,使得客户机通过远程调用1个服务器提供函数,它使用IDL(Interface Definition Language)来定义函数接口及参数形式。
在这里插入图片描述

gRPC仍然支持上述工作原理,但又做了重要改进,已越来越多的项目所采用。

gRPC有主要优点

gRPC是搭建分布式应用接口和客户端的框架。在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像它是本地对象一样,可以更容易创建分布式应用程序和服务。与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定可以远程调用的方法及其参数和返回类型。在服务端,服务端实现这个接口并运行一个 gRPC 服务器来处理客户端调用。在客户端有一个stub,负责参数序列化及发起调用请求

gRPC有许多优点,令采用这项技术的团队受益:

1)gRPC 在消息发送端,按protobuf 协议定义消息内容格式并进行序列化,接收侧收到消息后,采用protobuf协议反序列化读取内容。protobuf 非常节省资源,因此速度比json快了8倍,xml都60%以上。

在这里插入图片描述

2)gRPC 基于HTTP/2协议,支持multiplexing多路复用,而HTTP/1.1只能顺序处理。 并且gRPC采用了包头压缩来进一步减少网络开销。
在这里插入图片描述

3)Streaming流式处理,gRPC 的核心概念之一,也就是客户机发送多个请求,服务机可以在1个响应中回复。 还支持双向流式处理RPC, 客户端和服务器同时相互发送消息,而无需等待响应。
在这里插入图片描述

4) gRPC 客户端和服务器不必采用同一种语言编写, 如C++, Java, Go、Python 或 Ruby 中的客户端可以轻松地调用在 Java 创建 gRPC 服务器。

对于快速实现简单RPC编程,也可以选择 Python内置的 xmlrpc 模块,具体可以参考本人另一篇博文( 点击阅读

gRPC的基本用法

还是用实例代码来学习用法,
下面的例子要实现的目标: 服务器提供1个greet 函数,客户机通过gRPC调用。

1)开发环境:

python3.10.5

gRPC相关包:

  • grpcio
  • grpcio-tools
  • protobuf

建立1个新目录sample 做为项目根目录,其下再建1个 proto_files子目录
mkdir sample
cd sample
mkdir proto_files

2) 定义 1个 greeting.proto 文件

在 目录 sample/proto_files/下创建1个 新文件greeting.proto

syntax = "proto3";

message ClientInput {
   string greeting = 1;
   string name = 2;
}
message ServerOutput {
   string message = 1;
}

service Greeter {
   rpc greet (ClientInput) returns (ServerOutput) {}
}

代码说明:
syntax = "proto3";表示 Protobuf 版本号;

message ClientInput {
   string greeting = 1;
   string name = 2;
} 

在上面的代码块中,我们定义了1个消息 ClientInput,用于传入数据,它包含两个属性,“greeting”和“name”,它们都是字符串。客户端应该将“ClientInput”类型的对象发送到服务器。

message ServerOutput {
   string message = 1;
}

在这里,还定义另1个消息“ServerOutput”,用作服务器的返回值。

service Greeter {
   rpc greet (ClientInput) returns (ServerOutput) {}
}

此语句块定义了服务接口的名称为“Greeter”,每个接口可以包含多个函数,本例定义了1个接口函数“greet”。输入数据类型为“ClientInput”,返回类型为“ServerOutput”。

2) 编译proto文件

为 Protobuf 类和 gRPC 类生成基础代码。执行以下命令
python -m grpc_tools.protoc -I .\proto_files\ --python_out=. --grpc_python_out=. greeting.proto
在根目录下生成2文件
Protobuf class code: python/greeting_pb2.py
Protobuf gRPC code: python/greeting_pb2_grpcpb2.py

3) 编写服务器端代码 server.py
from concurrent import futures

import grpc
import greeting_pb2
import greeting_pb2_grpc

class Greeter(greeting_pb2_grpc.GreeterServicer):
    def greet(self, request, context):
        print("Got request " + str(request))
        return greeting_pb2.ServerOutput(message='{0} {1}!'.format(request.greeting, request.name))

def server():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=2))
    greeting_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port('[::]:50051')
    print("gRPC starting")
    server.start()
    server.wait_for_termination()

if __name == “__main__":
    server()
4) 编写客户端代码 client.py
import grpc

import greeting_pb2
import greeting_pb2_grpc

def run():
    """ 
    1. 先增加1个channel连接 
    2. 建立1个Stub
    3。调用服务器上的函数接,并获取 response.
    """
    with grpc.insecure_channel('localhost:50051') as channel:
        stub = greeting_pb2_grpc.GreeterStub(channel)
        response = stub.greet(
            greeting_pb2.ClientInput(name='小王', greeting="你好"))
    print("Greeter client received following from server: " + response.message)
    
if __name == “__main__":
	run()

名词解释

  • Channel 即 gRPC 通道,提供与指定主机和端口上的 gRPC 服务器的连接。它在创建客户端stub时使用。客户端可以指定通道参数来修改 gRPC 的默认行为,例如打开或关闭消息压缩。通道具有状态,包括已连接和空闲
  • stub 英文是指树桩的意思,可以把channel 理解为“网线”,stub理解为"网卡", 收发消息都是通过stub来进行的。

gRPC 如何处理关闭通道取决于语言。某些语言还允许查询通道状态。

5) 运行测试

打开两个窗口,分别运行 grpc_server.py grpc_client.py
client.py 每运行一次,服务器端会打印相应执行内容。至此客户端通过gRPC方式调用服务器提供的函数greet().

在这里插入图片描述

成长之路,道阻且长,静心勤勉
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值