zoukankan      html  css  js  c++  java
  • 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,即客户端发起一次请求,服务器可以返回多个响应信息,典型的例子有:客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端:

    通过protobuf编译器和Protocol Buffers生成代码:

    python3 -m grpc_tools.protoc -I. --python_out=.. --grpc_python_out=.. simple_calculate.proto

    服务端开启服务器,对外提供rpc调用流程:

    客户端rpc调用流程:

    Zookeeper服务注册与发现策略:

    服务注册:

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

    服务治理发现:

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

    服务端实现代码:

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

    客户端实现代码:

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

    服务测试:

    开启三个服务,地址分别是 host:8003  host:8005  host:8009,客户端开启两个,client1 和 client2 ,测试结果:

     

    已经成功注册了三个server到Zookeeper,客户端1使用的是8003端口的server,客户端2使用的是8005端口的server;grpc框架对于完整的rpc实现来说,实质上是封装了 网络传输、数据协议的打包解包,使得实现rpc更加简单,其本质仍然是遵守rpc的实现原理的

    完整的代码详见我的git:simple_calculate_service

  • 相关阅读:
    Spring Boot
    Spring Boot Tomcat配置详解
    Spring Boot读取配置的 5 种方式
    Spring Boot日志集成实战
    Spring Boot国际化开发实战
    Spring Boot整合 Thymeleaf 模板引擎
    Spring Boot Debug调试
    Spring Boot实现热部署
    Exchange Cards(dfs)
    Dungeon Master
  • 原文地址:https://www.cnblogs.com/FG123/p/10391759.html
Copyright © 2011-2022 走看看