python3和grpc的微服务探索实践

python3和grpc的微服务探索实践对于微服务的实践,一般都是基于Java和Golang的,博主最近研究了下基于Python的微服务实践,现在通过一个简单的服务来分析Python技术栈的微服务实践
技术栈:Python3 + grpc + Zookeeper
服务API:通过学科获取相应的题型
grpc:由Google公司开源的高性能RPC框架,消息协议使用Google自家开源的Protocol Buffers协议机制,传输使用HTTP2.0标准,支持双向流和连接多路复用
Protocol Buffers部分:

syntax = "proto3"; message Subject { string name = 1; }message QuestionType { string name = 1; }service SimpleRpcServer { // server streaming rpc // 客户端发送学科,服务端多次返回该学科包含的题型 rpc GetSubjectQuestionTypes (Subject) returns (stream QuestionType) { } }

这里定义grpc的接口类型为服务器流式RPC,即客户端发起一次请求,服务器可以返回多个响应信息,典型的例子有:客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端:
python3和grpc的微服务探索实践
文章图片


通过protobuf编译器和Protocol Buffers生成代码:
python3 -m grpc_tools.protoc -I. --python_out=.. --grpc_python_out=.. simple_calculate.proto


服务端开启服务器,对外提供rpc调用流程:
python3和grpc的微服务探索实践
文章图片

【python3和grpc的微服务探索实践】

客户端rpc调用流程:
python3和grpc的微服务探索实践
文章图片

Zookeeper服务注册与发现策略:
服务注册:
1 def register_zk(host, port): 2""" 3注册到zookeeper 4""" 5zk = KazooClient(hosts='{host}:{port}'.format( 6host=settings_info["zookeeper"]["host"], 7port=settings_info["zookeeper"]["port"]) 8) 9zk.start() 10zk.ensure_path('/rpc_calc')# 创建根节点 11value = https://www.it610.com/article/json.dumps({'host': host, 'port': port}) 12 13# 创建服务子节点 14zk.create( 15'/rpc_calc/calculate_server', 16value.encode(), 17ephemeral=True, 18sequence=True 19)

服务治理发现:
1def _get_servers(self, event=None): 2""" 3从zookeeper获取服务器地址信息列表 4""" 5servers = self._zk.get_children( 6'/rpc_calc', watch=self._get_servers 7) 8print(servers) 9self._servers = [] 10for server in servers: 11data = https://www.it610.com/article/self._zk.get('/rpc_calc/' + server)[0] 12if data: 13addr = json.loads(data.decode()) 14self._servers.append(addr) 15 16def get_server(self): 17""" 18随机选出一个可用的服务器 19""" 20return random.choice(self._servers)


服务端实现代码:
1 class SimpleRpcServerServicer(calculate_grpc.SimpleRpcServerServicer): 2""" 3实现被调用方法的具体代码 4""" 5 6def __init__(self): 7self.subject_question_type_db = { 8'Chinese': ['单选', '多选', '填空', '解答', '问答', '作文'], 9'Math': ['单选', '填空', '解答'], 10'English': ['单选', '填空', '作文'], 11'Physics': ['单选', '多选', '填空', '解答'], 12'Chemistry': ['单选', '多选', '填空', '解答'], 13'Biology': ['单选', '多选', '填空', '解答'], 14'History': ['单选', '多选', '填空', '解答', '问答'] 15} 16 17def GetSubjectQuestionTypes(self, request, context): 18""" 19服务器流式RPC调用 根据subject获取question_types 20:param request: 21:param context: 22:return: 23""" 24subject = request.name 25question_types = self.subject_question_type_db.get(subject) 26for question_type in question_types: 27yield calculate_pb2.QuestionType(name=question_type)


客户端实现代码:
1 def invoke_get_subject_question_types(stub): 2""" 3根据学科获取题型 4Server Streaming RPC 服务器流式RPC客户端发送,服务器响应多个 5:param stub: 6:return: 7""" 8subject = calculate_pb2.Subject(name='Chinese') 9question_types = stub.GetSubjectQuestionTypes(subject) 10for question_type in question_types: 11print(question_type.name)


服务测试:
开启三个服务,地址分别是 host:8003host:8005host:8009,客户端开启两个,client1 和 client2 ,测试结果:
python3和grpc的微服务探索实践
文章图片

python3和grpc的微服务探索实践
文章图片

已经成功注册了三个server到Zookeeper,客户端1使用的是8003端口的server,客户端2使用的是8005端口的server;grpc框架对于完整的rpc实现来说,实质上是封装了 网络传输、数据协议的打包解包,使得实现rpc更加简单,其本质仍然是遵守rpc的实现原理的
完整的代码详见我的git:simple_calculate_service
posted @ 2019-02-25 21:25 Harvard_Fly 阅读( ...) 评论( ...) 编辑 收藏

    推荐阅读