consul初体验记录

 nadia     2019-08-12     1506     0   

欢迎来到银盒子的世界~

项目要转微服务嘛,用到了consul,下边对舒勇过程做一个简单的记录

首先是参考了这篇博客:https://www.cnblogs.com/yuzhenjie/p/9398569.html

下边粘贴一下原文内容  ↓↓↓↓

python与consul 实现gRPC服务注册-发现            

背景

通过对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服务挂掉会影响所有相关的项目,所以最好还是有从节点。


粘贴结束↑↑↑↑↑



后来发现这个博客,地址:https://www.cnblogs.com/viter/p/11018953.html

粘贴如下↓↓↓↓↓↓↓↓


本次实验使用物料准备:

1、 Consul 服务器集群 3 台,系统为 Centos7.0

下载二进制包

访问 Consul 的官方网站:https://www.consul.io,看懂非常牛逼的一句话,让打造服务网格变简单!然后大大的屏幕上放着两个按钮:Download or Get Started;表示你要么立即开始干要么先学一段,右边就是一个高大上的视频操作介绍,看着就让人热血沸腾;这我哪里能忍,点击下载:https://www.consul.io/downloads.html ,话不多说,打开服务器的 ssh,果断敲下一梭子:

cd /tmp
wget https://releases.hashicorp.com/consul/1.5.1/consul_1.5.1_linux_amd64.zipunzip consul_1.5.1_linux_amd64.zip -d /usr/local/bin

编辑 /etc/profile 文件,添加环境变量,保存后退出。

vi /etc/profile
export CONSUL_HOME=/usr/local/bin/consul
export PATH=$PATH:CONSUL_HOME// 使用环境变量配置生效source /etc/profile

验证 Consul 安装是否成功,在命令行输入:consul

consul --version

输出结果:

看到这个结果,我心里是很安慰的,不过如此嘛,一点都不像其它软件,从下载源码到编译,从安装 gcc 到 gdi+ 的依赖,先跑1万个依赖文件的列表,Consul 也太 easy 了。

入门必学必记文档

帮助文档:https://www.consul.io/docs/agent/options.html

安装好 Consul 后,在启动程序之前,需要掌握一些配置参数,通过掌握这些参数,可以一次性的成功运行 Consul 服务器集群,常用的参数如下:

参数名称用途
-server此标志用于控制代理是运行于服务器/客户端模式,每个 Consul 集群至少有一个服务器,正常情况下不超过5个,使用此标记的服务器参与 Raft一致性算法、选举等事务性工作
-client表示 Consul 绑定客户端接口的IP地址,默认值为:127.0.0.1,当你有多块网卡的时候,最好指定IP地址,不要使用默认值
-bootstrap-expect预期的服务器集群的数量,整数,如 -bootstrap-expect=3,表示集群服务器数量为3台,设置该参数后,Consul将等待指定数量的服务器全部加入集群可用后,才开始引导集群正式开始工作,此参数必须与 -server 一起使用
-data-dir存储数据的目录,该目录在 Consul 程序重启后数据不会丢失,指定此目录时,应确保运行 Consul 程序的用户对该目录具有读写权限
-node当前服务器在集群中的名称,该值在整个 Consul 集群中必须唯一,默认值为当前主机名称
-bindConsul 在当前服务器侦听的地址,如果您有多块网卡,请务必指定一个IP地址(IPv4/IPv6),默认值为:0.0.0.0,也可用使用[::]
-datacenter代理服务器运行的数据中心的名称,同一个数据中心中的 Consul 节点必须位于同一个 LAN 网络上
-ui启用当前服务器内部的 WebUI 服务器和控制台界面
-join该参数指定当前服务器启动时,加入另外一个代理服务器的地址,在默认情况下,如果不指定该参数,则当前代理服务器不会加入任何节点。可以多次指定该参数,以加入多个代理服务器,
-retry-join用途和 -join 一致,当第一次加入失败后进行重试,每次加入失败后等待时间为 30秒
-syslog指定此标志意味着将记录 syslog,该参数在 Windows 平台不支持

启动 Consul

终于来到这一步了,目前我手上有 3 台嗷嗷待哺的 Centos-7.0 服务器,他们的IP地址分别是:

  • 172.16.1.218

  • 172.16.1.219

  • 172.16.1.220

分别在三台服务器输入以下对应的命令

// 172.16.1.218consul agent -server -ui -bootstrap-expect=3 -data-dir=/data/consul -node=agent-1 -client=0.0.0.0 -bind=172.16.1.218 -datacenter=dc1// 172.16.1.219consul agent -server -ui -bootstrap-expect=3 -data-dir=/data/consul -node=agent-2 -client=0.0.0.0 -bind=172.16.1.219 -datacenter=dc1 -join 172.16.1.218// 172.16.1.220consul agent -server -ui -bootstrap-expect=3 -data-dir=/data/consul -node=agent-3 -client=0.0.0.0 -bind=172.16.1.220 -datacenter=dc1 -join 172.16.1.218

上面的命令几乎无法再精简,简单来说,就是指定了 consul(-server) 集群有3台(-bootstrap-expect=3 )服务器(-node),指定当前主机客户端侦听地址为( -client=0.0.0.0 ),因为我有多块网卡,如果不指定,无法运行127.0.0.1。绑定了当前主机的IP地址(-bind),指定了一个数据中心的名称(-datacenter=dc1),后两台服务器在启动的时候加入第一台代理服务器(-join 172.16.1.218),同时指定了启用每台服务器的内置 WebUI 服务器组件(-ui),当三台服务器都正确运行起来以后,Consul 集群将自动选举 leader,自动进行集群事务,无需干预。

正常启动的服务器应该输出下面的信息

现在,我尝试通过某台服务器访问 Consul 的 WebUI 控制台,web 控制台默认端口为:8500,查看集群状态,输入地址:

http://172.16.1.218:8500

上面的IP地址可以是 3 台 Consul 服务器中的任意一台,打开网页后,转向 Nodes 菜单,可以看到,由 3 台代理服务器组成的集群已成功启动和运行,健康检查都是草原的颜色,非常的健康。

在网页控制台中,除了了看到 Consul 的服务器集群的信息,还可以对 key/value 、ACL 等进行管理。


粘贴完成↑↑↑↑↑↑↑↑


发表评论