背景

通过对gRPC的介绍我们知道,当正常启动服务后,我们只需要知道ip,port就可以进行gRPC的连接。可以想到,这种方式并不适合用于线上环境,因为这样直连的话就失去了扩展性,当需要多机部署的时候,就无法在线上环境直接使用,而且当线上项目连接的那台服务器宕了的话,整个项目也会出错,这并不是我们想要的结果。

于是,我们需要一个服务注册与发现的机制。也就是说当我们的rpc服务启动的时候注册到另一个服务器,然后客户端连接的时候去查找对应的服务,得到相应的ip,port,然后就可以顺利进行连接了。这种方式也就是服务注册与发现,目前有zoomkeper, consul, 因为自己对zookeeper不熟悉,所以这里选用consul。整个流程如图所示

consul 的安装

  1. 通过docker

    运行如下命令:

    docker run -d -p 8500:8500 consul consul agent -data-dir=/consul/data -config-dir=/consul/config -dev -client=0.0.0.0 -bind=0.0.0.0

  2. 通过其它方式

    安装方式参考https://www.consul.io/intro/getting-started/install.html

    安装完后运行:

    consul agent --data-dir . -server -ui -bootstrap -bind=127.0.0.1

无论哪种方式,运行完之后在浏览器中打开 http://127.0.0.1:8500/ui, 可以看到如下内容

服务注册

已之前介绍的gRPC代码为基础,我们加入服务注册部分(注:本人环境为python3, 需要python2的,自己进行修改)

 import time
import grpc
import consul
import json
from concurrent import futures import test_pb2_grpc
import test_pb2 def test(request, context):
# 实际调用到的函数
json_response = test_pb2.JSONResponse()
json_response.rst_string = json.dumps({"ret":"Hi gRPC"})# 构造出proto文件中定义的返回值格式
return json_response class OrderHandler(test_pb2_grpc.OrderHandlerServicer):
def create_order(self, request, context):
return test(request, context) def register(server_name, ip, port):
c = consul.Consul() # 连接consul 服务器,默认是127.0.0.1,可用host参数指定host
print(f"开始注册服务{server_name}")
check = consul.Check.tcp(ip, port, "10s") # 健康检查的ip,端口,检查时间
c.agent.service.register(server_name, f"{server_name}-{ip}-{port}",
address=ip, port=port, check=check) # 注册服务部分
print(f"注册服务{server_name}成功") def unregister(server_name, ip, port):
c = consul.Consul()
print(f"开始退出服务{server_name}")
c.agent.service.deregister(f'{server_name}-{ip}-{port}') 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))
register("order_server", "0.0.0.0", 12006)
server.start()
try:
while True:
time.sleep(186400)
except KeyboardInterrupt:
unregister("order_server", "0.0.0.0", 12006)
server.stop(0) serve()

要运行此服务需要先安装 python-consul pip install python-consul

运行此服务,在浏览器中会出现我们刚刚注册的服务,和可用节点,健康信息,如图

当使用ctrl+c 退出服务时,会取消注册。也就是会从consul列表里消失。

注意: 当健康检测失败时,并不意味着服务有问题,仅表示consul服务器和对应的rpc服务的端口连不上而已

rpc客户端连接

客户端需要向consul服务器请求,得到可用的rpc服务的ip,端口,在进行连接,我们还是基于之前的客户端代码进行修改,完整代码如下:

 import grpc
from dns import resolver
from dns.exception import DNSException import test_pb2_grpc
import test_pb2 # 连接consul服务,作为dns服务器
consul_resolver = resolver.Resolver()
consul_resolver.port = 8600
consul_resolver.nameservers=["127.0.0.1"] def get_ip_port(server_name):
'''查询出可用的一个ip,和端口'''
try:
dnsanswer = consul_resolver.query(f'{server_name}.service.consul', "A")
dnsanswer_srv = consul_resolver.query(f"{server_name}.service.consul", "SRV")
except DNSException:
return None, None
return dnsanswer[0].address, dnsanswer_srv[0].port ip, port = get_ip_port("order_server") channel = grpc.insecure_channel(f"{ip}:{port}")
stub = test_pb2_grpc.OrderHandlerStub(channel)
# 要完成请求需要先构造出proto文件中定义的请求格式
ret = stub.create_order(test_pb2.OrderRequest(phone="12990", price="50")) print(ret.rst_string)

总结

至此,我们已经搭建好了一套简单服务注册-发现系统。当然consul的功能远不止这一点,它还支持分布式,多节点部署。需要了解更多,可以去官网做进一步了解。

踩过的坑

  • 在示例中,我们只捕获了ctrl+c 信号,在实际中,服务会因为一些奇怪的问题宕掉,而此时,该节点信息会一直在consul里面,除非手动注销,所以需要捕获所有异常信号。
  • 单节点的时候,consul服务挂掉会影响所有相关的项目,所以最好还是有从节点。

python与consul 实现gRPC服务注册-发现的更多相关文章

  1. 服务注册发现、配置中心集一体的 Spring Cloud Consul

    前面讲了 Eureka 和 Spring Cloud Config,今天介绍一个全能选手 「Consul」.它是 HashiCorp 公司推出,用于提供服务发现和服务配置的工具.用 go 语言开发,具 ...

  2. 基于 Consul 实现 MagicOnion(GRpc) 服务注册与发现

    0.简介 0.1 什么是 Consul Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置. 这里所谓的服务,不仅仅包括常用的 Api 这些服务,也包括软件开发过程 ...

  3. 微服务学习笔记(2)——使用Consul 实现 MagicOnion(GRpc) 服务注册和发现

    原文:微服务学习笔记(2)--使用Consul 实现 MagicOnion(GRpc) 服务注册和发现 1.下载打开Consul 笔者是windows下面开发的(也可以使用Docker). 官网下载w ...

  4. Docker+Consul+Registrator 实现服务注册与发现

    Docker+Consul+Registrator实现服务注册与发现 逻辑图 实现nginx节点自动化加入容器IP代理 1.三台Consul agent server作为高可用通过Consul Tem ...

  5. 服务注册发现consul之二:在Spring Cloud中使用Consul实现服务的注册和发现

    首先安装consul环境,参照之前的文章:<服务注册发现consul之一:consul介绍及安装>中的第一节介绍. Spring Cloud使用Consul的服务与发现 1.导入依赖pri ...

  6. Consul 多数据中心下的服务注册发现与配置共享

    1. Consul简介   Consul是HashiCorp公司推出的开源软件,它提供了一套分布式高可用可横向扩展的解决方案,能为微服务提供服务治理.健康检查.配置共享等能力.   Eurake2.x ...

  7. 基于docker,consul,consul-template, registrator, nginx服务注册发现集群

      介绍 该工程主要实现服务的自动注册发现,从而达到提高运维效率,做到服务的自动发现和动态扩展. 服务注册发现 服务启动后自动被发现 动态变更负载均衡 自动伸缩 工具 1.Registrator 这是 ...

  8. 服务注册发现与注册中心对比-Eureka,Consul,Zookeeper,Nacos对比

    服务注册发现与注册中心对比-Eureka,Consul,Zookeeper,Nacos对比 注册中心简介 流程和原理 基础流程 核心功能 1.Eureka.Consul.Zookeeper三者异同点 ...

  9. spring-cloud-consul 服务注册发现与配置

    下面是 Spring Cloud 支持的服务发现软件以及特性对比(Eureka 已停止更新,取而代之的是 Consul): Feature euerka Consul zookeeper etcd 服 ...

随机推荐

  1. Mac 系统变量

    vim .bash_profile ========================= MAVEN_HOME = < ... > export MAVEN_HOME =========== ...

  2. [引]雅虎日历控件 Example: Two-Pane Calendar with Custom Rendering and Multiple Selection

    本文转自:http://yuilibrary.com/yui/docs/calendar/calendar-multipane.html This example demonstrates how t ...

  3. OAuth2.0和企业内部统一登录,token验证方式,OAuth2.0的 Authorization code grant 和 Implicit grant区别

    统一登录是个很多应用系统都要考虑的问题,多个项目的话最好前期进行统一设计,否则后面改造兼容很麻烦: cas认证的方式:新公司都是老项目,用的是cas认证的方式,比较重而且依赖较多,winform的项目 ...

  4. 前端如何做好SEO优化

    https://www.cnblogs.com/weiyf/p/9511021.html 一:什么是SEO? 搜索引擎优化(Search Engine Optimization),简称SEO.是按照搜 ...

  5. Spring课程 Spring入门篇 1-2Spring简介

    课程链接: 1 Spring是什么? 2 为什么是Spring 3 Spring的作用: 4 适用范围 1 Spring是什么? a 开源框架 b 轻量级的控制反转(Ioc)和面向切面编程(AOP)的 ...

  6. The tenth day

    Why the long face? 你为什么不高兴,你为什么扳着脸,愁眉苦脸. Why the long face? Are you feeling down again? 你脸怎么这么臭,你又心情 ...

  7. Android基础Activity篇——销毁活动

    销毁活动只需要添加 finish(); 这个方法即可.相当于back键.

  8. Linux centos6.x 配置免密码登录

    免密码登录主要就是被访机器提供公匙给访问者,然后访问者使用ssh协议时可以使用所配置好的公匙验证.这样就免去了输入密码的麻烦. 某些集群例如hadoop,一般都需要将主机和其他机器间配置无密码公匙认证 ...

  9. HTML5 data-* 自定义属性操作及其注意点

    在HTML5中添加了data-*的方式来自定义属性,所谓data-*实际上上就是data-前缀加上自定义的属性名,命名可以用驼峰命名方式,但取值是必需全部使用小写(后面会说),使用这样的结构可以进行数 ...

  10. Java 开发小常识

    从理论上来讲Java做的系统并不比其他语言开发出来的系统更占用内存,那么为什么却有这么多理由来证明它确实占内存呢?两个字,陋习. 1.别用new Boolean().在很多场景中Boolean类型是必 ...