用python 搭建一个grpc服务

grpc协议概述

grpc是一种基于某种协议实现不同机器间进行通信的服务框架。不同机器可以是不同的服务端、客户端,当服务端实现好某些功能后,提供一个服务接口,供不同客户端进行接口调用,从而让不同客户端都能够“享用”到服务端提供的功能。在实际业务场景,比如我是做算法的,那么当我的模型训练完成后,要放到线上让别人调用,则经常是以grpc的方式进行实现的。简单流程就是我写个服务端,实现接收客户端传来的数据,并进行模型推理计算,计算结果再返回客户端,那么客户端实际只需要提供数据即可得到它们想要的结果,中间数据的处理过程均由服务端来完成。

搭建通信过程

协议文件

定义一个文件名为recevicedata.proto文件(可能需要下载插件以识别这个文件),并输入以下代码

// 这里我们用的是proto3版本,版本号是一定要指定的哦!
syntax = "proto3";
 
import "google/protobuf/wrappers.proto";
 
service LabelService {
  /**
  样本集接口
   */
  rpc receiveSample(SampleRequestList) returns (google.protobuf.BoolValue) {}
}
message SampleRequestList {
  repeated SampleRequest reqList = 1;
}
 
message SampleRequest {
  /**
  标签值
   */
  string labelValue = 1;
  /**
  样本集数据
   */
  string text = 2;
}

运行以下命令

python -m grpc_tools.protoc -I. --python_out=../grpc_file --grpc_python_out=../grpc_file receivedata.proto

会在grpc_file文件目录下生成两个python文件

服务端

创建server.py文件,输入:

import logging
import sys
 
sys.path.append('..')
import time
import datetime
from concurrent import futures
 
import grpc_file
import jieba
import re
import grpc
 
from grpc_file import ReceiveData_pb2_grpc
# 这个地方的BoolValue可能会飘红,不用管,用就行了
from google.protobuf.wrappers_pb2 import BoolValue
 
jieba.setLogLevel(log_level=0)
pattern = re.compile('(?:https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]')
logger = logging.getLogger('logger')
# 设置日志等级_
logger.setLevel(logging.INFO)
 
 
class ReceiveDataServer:
    def __init__(self, host, port):
        self.host = host
        self.port = port
 
    def match_url(self, text):
        """
        去除url
        :param text:
        :return:
        """
        clear = pattern.sub('', text)
        return clear
 
    def seg_sentence(self, data):
        """
        分词
        :param data:
        :return:
        """
        data = self.match_url(data)
        seg_text = jieba.cut(data.replace('\t', '').replace('\n', '').replace(' ', ''))
        context = ' '.join(seg_text)
        return context
 
    def receiveSample(self, request, context):
        """
        接收数据的grpc服务接口,该函数的名称要和proto文件中定义的接口名保持一致
        :param request:
        :param context:
        :return:
        """
        requestlist = request.reqList
        try:
            for item in requestlist:
                text = item.text.replace('\n', '。').replace('\r', '。')
                text = self.seg_sentence(text)
                print(datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S'),
                  '*** 添加标签:{},添加文本:{}... ***'.format(item.labelValue, text[:10]))
            return BoolValue(value=True)
        except:
            return BoolValue(value=False)
 
 
def serve(host, port):
    # 启动 rpc 服务
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=8))
    ReceiveData_pb2_grpc.add_LabelServiceServicer_to_server(ReceiveDataServer(host, port), server)
    server.add_insecure_port('{}:{}'.format(host, port))
    server.start()
    print('Grpc server connect successful!')
 
    try:
        while True:
            time.sleep(600)
            print(datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S'))
    except KeyboardInterrupt:
        print(datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S'))
        server.stop(0)
 
 
if __name__ == '__main__':
    # host和port写上服务端运行的机器ip和端口;
    serve(host='xxx.xxx.xxx.xxx', port=50001)

客户端

创建client.py 文件,输入:

import sys
 
sys.path.append('..')
import grpc
from grpc_file import ReceiveData_pb2, ReceiveData_pb2_grpc
 
 
def run():
    # 连接 rpc 服务器,ip和端口号必须和服务端设置的一致
    channel = grpc.insecure_channel('192.xxx.xxx.xx:50001')
    # 调用 rpc 服务
    stub = ReceiveData_pb2_grpc.LabelServiceStub(channel)
    requestlist = ReceiveData_pb2.SampleRequestList()
    for data in range(10):
        label = str(data)
        text = '第{}个标签的数据'.format(label)
        # 由于我们在proto文件中定义的接收数据格式为List,所以这里我们需要先定义一个向List中添加数据的对象
        request = requestlist.reqList.add()
        request.labelValue = label
        request.text = text
    response = stub.receiveSample(requestlist)
    print(response)
 
if __name__ == '__main__':
    run()

最后运行server.py和client.py文件,会得到以下输出
在这里插入图片描述
至此,一个简单的grpc协议搭建完成。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值