Python gRPC
-
簡介
grpc 是google 開源的一款rpc服務框架,可以輕鬆的實現跨語言的微服務,將專案中的各個模組獨立出來,單獨部署,獨立升級,也可以根據模組的情況進行不同語言的變成。
gRPC也是一個C/S框架,使用的是HTTP2 協議進行通訊。 -
準備.proto檔案
syntax = "proto3";
package order;
message OrderRequest {
string phone = 1;
string price = 2;
map<string, string> request_arg = 3;//便於欄位擴充套件
}
message JSONResponse{
string rst_string = 1; //統一返回json字串作處理
}
service OrderHandler {
// format a list of events.
rpc create_order (OrderRequest) returns (JSONResponse) {}
}
其中:
message: 定義資料結構
service: 定義介面的名字,引數,
- 生成所需檔案(伺服器和客戶端均需要)
python -m grpc_tools.protoc -I./ --python_out=./ --grpc_python_out=./ ./*.proto
- 編寫server端程式碼
import time
import test_pb2_grpc
import grpc
from concurrent import futures
from order.views import test
import os
class OrderHandler(test_pb2_grpc.OrderHandlerServicer):
def create_order(self, request, context):
return test(request, context)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
test_pb2_grpc.add_OrderHandlerServicer_to_server(
OrderHandler(), server)
server.add_insecure_port(`[::]:{}`.format(12006))
server.start()
try:
while True:
time.sleep(186400)
except KeyboardInterrupt:
server.stop(0)
serve()
- 對應的views.py 檔案
from django.shortcuts import render
from django.http import JsonResponse
# Create your views here.
import test_pb2
import json
from django.http import HttpRequest
def grpc_request(func):
“”“
將grpc請求重新構造成django requst,
並封裝相應返回值
”“”
def f(request, context):
f = lambda x:{k:v for k,v in x.items()} if hasattr(x, `items`) else x
args = {i[0].name:f(i[1]) for i in request.ListFields() }
# 構造django request 物件,並新增引數資訊
dj_request = HttpRequest()
dj_request.GET = args
# dj_request.POST = args
# dj_request._body = json.dumps(args)
dj_request.META = args
ret = func(dj_request)
# 處理django的response 物件, 轉換為grpc的物件
json_response = test_pb2.JSONResponse()
json_response.rst_string = ret.getvalue()
return json_response
return f
def check_inenty(func):
def f(request):
if "identy" not in request.META:
return JsonResponse(dict(status=403))
else:
return func(request)
return f
@grpc_request
@check_inenty
def test(request):
return JsonResponse(dict(test=1, name="333"))
- 編寫客戶端程式碼進行 測試 client.py
import grpc
import test_pb2_grpc
import test_pb2
channel = grpc.insecure_channel("127.0.0.1:12006")
stub = test_pb2_grpc.OrderHandlerStub(channel)
ret = stub.create_order(test_pb2.OrderRequest(phone="12990", price="50"))
print(ret.rst_string)