Grpc初體驗
前言
因爲最近工作涉及到了grpc, 但是不是很瞭解這個框架, 所以就看了一手 grpc官方文檔, 克隆下來代碼簡單的瞭解一下
概念
定義一個服務, 指定其可以被遠程調用的方法及其參數和返回類型。gRPC 默認使用 protocol buffers 作爲接口定義語言,來描述服務接口和有效載荷消息結構。允許定義四種服務方法
1 單項 RPC,即客戶端發送一個請求給服務端,從服務端獲取一個應答,就像一次普通的函數調用
2 服務端流式 RPC,即客戶端發送一個請求給服務端,可獲取一個數據流用來讀取一系列消息。客戶端從返回的數據流裏一直讀取直到沒有更多消息爲止。
3 客戶端流式 RPC,即客戶端用提供的一個數據流寫入併發送一系列消息給服務端。一旦客戶端完成消息寫入,就等待服務端讀取這些消息並返回應答
4 雙向流式 RPC,即兩邊都可以分別通過一個讀寫數據流來發送一系列消息。這兩個數據流操作是相互獨立的,所以客戶端和服務端能按其希望的任意順序讀寫,
主要使用
gRPC 提供 protocol buffer 編譯插件,能夠從一個服務定義的 .proto 文件生成客戶端和服務端代碼。通常 gRPC 用戶可以在服務端實現這些API,並從客戶端調用它們。
測試
服務端
測試使用的話就是按照官方文檔的教程來的
git clone https://github.com/grpc/grpc.git
拉一手代碼然後直接進到demo目錄就可以, 我主要看了一下 Python和 Go的, 目錄 grpc/examples/python/helloworld, 裏面的代碼都是生成好的, 可以直接使用, 如果有興趣的也可以按照教程從頭開始
在目錄裏 greeter_server.py 是服務端, 在裏面定義了一個Greeter的類, 包括裏面的一個 SayHello 方法(接受參數, 返回響應)
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Yes, %s!' % request.name)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
可以看到在server裏面首先定義了一個最大處理數爲10的線程池, 然後將 Greeter 類作爲服務添加, 在添加50051作爲服務端口, start啓動服務
客戶端
def run():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
a = time.time()
with grpc.insecure_channel('localhost:50051') as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='小飛'))
print(response)
print("time = ", time.time()-a)
print("Greeter client received: " + response.message)
客戶端就比較簡單了, 通過grpc 連上50051端口攜帶參數發起請求, 再接受服務端返回的詳情就ok
proto文件
gRPC 默認使用 protocol buffers 作爲接口定義語言, 所以需要編寫 proto文件定義 gRPC接口, 進行編譯生成 helloworld_pb2 和helloworld_pb2_grpc文件, 也就是客戶端和服務端之間的通信, 裏面會定義接口接收參數和返回參數.