文章目录
- 一、gRPC 简介
- 概述
- 协议缓冲区
- 二、gRPC 的 Hello World
- 协议缓冲区
- gRPC 服务端
- gRPC 客户端
- 启动 gRPC
一、gRPC 简介
概述
gRPC是搭建分布式应用接口和客户端的框架。在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像它是本地对象一样,可以更容易创建分布式应用程序和服务。与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定可以远程调用的方法及其参数和返回类型。在服务端,服务端实现这个接口并运行一个 gRPC 服务器来处理客户端调用。在客户端,客户端有一个存根(在某些语言中仅称为客户端),它提供与服务器相同的方法。
gRPC 客户端和服务器可以在各种环境中运行和相互通信——从 Google 内部的服务器到您自己的桌面——并且可以用任何 gRPC 支持的语言编写。例如,可以使用 Go、Python 或 Ruby 中的客户端轻松地调用在 Java 中创建 gRPC 服务器。
协议缓冲区
协议缓冲区, 是谷歌开源的结构化数据结构。
协议缓冲区中的数据和服务定义,可以参考:协议缓冲区。
例如,在 proto 文件中定义 gRPC 服务,将 RPC 方法参数和返回类型指定为协议缓冲区消息:
// 定义服务
service Greeter {
// 发送消息
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 包含用户名的请求消息
message HelloRequest {
string name = 1;
}
// 包含问候的响应信息
message HelloReply {
string message = 1;
}
使用在proto中定义的服务和数据结构,可以使用gRPC的插件来生成对应的grpc文件。
二、gRPC 的 Hello World
gRPC可以使用多种语言编写,下面使用python来实现一个简单的gRPC服务端和客服端。
一般来说写gRPC服务,需要三个文件:
-
.proto
文件:用于生成gRPC服务文件。 -
server
文件:定义 gRPC 服务端。 -
client
文件:定义 gRPC 客户端,调用服务端接口。
基本环境如下:
- python 3.10.2
协议缓冲区
定义协议缓冲区,新建一个hello.proto
文件,写入以下内容:
syntax = "proto3";
package hello;
message User {
string id = 1;
string name = 2;
}
message Reply {
string message = 1;
}
service UserInfo {
rpc Info (User) returns (Reply) {}
}
这个文件首先定义了两个数据结构,一个是用户的详细信息User,一个是用户信息格式化输出。
需要注意的是当一个message中定义多个变量时,赋值的编号不能相同,如User中的id和name分别是1和2。
然后定义了一个简单的服务UserInfo,将User传入,最后返回Reply(注意是returns,加了s)
最后使用gRPC的工具包,生成gRPC服务类:
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./hello.proto
它会生成两个文件hello_pb2.py
和hello_pb2_grpc.py
.
大致可以理解为:_pb2
中定义了数据结构。_pb2_grpc
中定义了相关的方法。
具体的含义可以去看:生成代码参考
gRPC 服务端
如下,定义 gRPC 服务端hello_server.py
,并堵塞监测本地50051端口,等待接收数据:
from concurrent import futures
import logging
import grpc
import hello_pb2
import hello_pb2_grpc
class UserInfo(hello_pb2_grpc.UserInfoServicer):
def Info(self, request, context):
return hello_pb2.Reply(message='id: %s; name: %s' % (request.id, request.name))
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
hello_pb2_grpc.add_UserInfoServicer_to_server(UserInfo(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
serve()
gRPC 客户端
如下,定义 gRPC 客户端hello_client.py
,通过接收参数,向本地50051端口,传输用户信息:
from __future__ import print_function
import logging, sys
import grpc
import hello_pb2
import hello_pb2_grpc
def run():
with grpc.insecure_channel('localhost:50051') as channel:
stup = hello_pb2_grpc.UserInfoStub(channel)
response = stup.Info(hello_pb2.User(id=sys.argv[1],name=sys.argv[2]))
print("用户信息: " + response.message)
if __name__ == '__main__':
logging.basicConfig()
run()
启动 gRPC
启动gRPC服务端 :
python hello_server.py
在另一个终端窗口中,启动gRPC客户端:
python hello_client.py 1 zhangsan
最后查看效果:
更多的用法可以参考: