• 一文带你学会 consul 基本使用和 Docker 部署


    本文演示 docker 下部署使用 consul。容器与宿主机的端口映射忽略,正常生产环境每个宿主机一个 consul,端口需要映射到宿主机

    zookeeper 和 consul 比较

    • 开发语言方面,zookeeper 采用 java 开发,安装的时候需要部署 java 环境;consul 采用 golang 开发,所有依赖都编译到了可执行程序中,即插即用。
    • 部署方面,zookeeper 一般部署奇数个节点方便做简单多数的选举机制。consul 部署的时候分 server 节点和 client 节点(通过不同的启动参数区分),server 节点做 leader 选举和数据一致性维护,client 节点部署在服务机器上,作为服务程序访问 consul 的接口。
    • 一致性协议方面,zookeeper 使用自定义的 zab 协议,consul 的一致性协议采用更流行的 Raft。
    • zookeeper 不支持多数据中心,consul 可以跨机房支持多数据中心部署,有效避免了单数据中心故障不能访问的情况。
    • 链接方式上,zookeeper client api 和服务器保持长连接,需要服务程序自行管理和维护链接有效性,服务程序注册回调函数处理 zookeeper 事件,并自己维护在 zookeeper 上建立的目录结构有效性(如临时节点维护);consul 采用 DNS 或者 http 获取服务信息,没有主动通知,需要自己轮训获取。
    • 工具方面,zookeeper 自带一个 cli_mt 工具,可以通过命令行登录 zookeeper 服务器,手动管理目录结构。consul 自带一个 Web UI 管理系统, 可以通过参数启动并在浏览器中直接查看信息。

    部署:

    拉取镜像

    docker search consul

    复制代码

    咱们用官方的镜像玩玩

    docker pull consul

    复制代码

    不指定 tag 就拉取 last,当前版本是 1.5.2

    启动 consul

    启动节点 1(server 模式)

    -node:节点的名称

    -bind:绑定的一个地址,用于节点之间通信的地址,可以是内外网,必须是可以访问到的地址

    -server:这个就是表示这个节点是个 SERVER

    -bootstrap-expect:这个就是表示期望提供的 SERVER 节点数目,数目一达到,它就会被激活,然后就是 LEADER 了

    docker run -d -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' --name=node1 consul agent -server -bind=172.17.0.2  -bootstrap-expect=3 -node=node1

    复制代码

    启动节点 2-3(server 模式)

    1. docker run -d -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' --name=node2 consul agent -server -bind=172.17.0.3 -join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}') -node=node2
    2. docker run -d -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' --name=node3 consul agent -server -bind=172.17.0.4 -join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}') -node=node3 -client=172.17.0.4

    复制代码

    -join:这个表示启动的时候,要加入到哪个集群内,这里就是说要加入到节点 1 的集群 -node-id:这个貌似版本 8 才加入的,这里用这个来指定唯一的节点 ID,可以查看这个 issue -client:这个表示注册或者查询等一系列客户端对它操作的 IP,如果不指定这个 IP,默认是 127.0.0.1。

    启动节点 4(client 模式)

    docker run -d -e 'CONSUL_LOCAL_CONFIG={"leave_on_terminate": true}' --name=node4 consul agent -bind=172.17.0.5 -retry-join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}')  -node=node4

    复制代码

    除了没有-server,其它都是一样的,没有这个就说明这个节点是 CLIENT

    查看下集群的状态

    docker exec -t node1 consul members

    复制代码

    4 个节点都列出来了。Status 表示它们的状态,都是 alive。Type 表示它们的类型,三个 SERVER 一个 CLIENT,和我们之前启动的一样。DC 表示数据中心,都是 dc1。

    节点异常 consul 的处理

    LEADER 挂了

    leader 挂了,consul 会重新选取出新的 leader,只要超过一半的 SERVER 还活着,集群是可以正常工作的。node1 是 leader,所以把这个容器停了。

    docker stop node1

    看看其他节

    日志(node2):

    日志打印,心跳检查 node1 的 ip 超时,接着开始选举。node2 被选举为新的 leader。我们查看下现在的 leader:

    curl http://172.17.0.4:8500/v1/status/leader

    复制代码

    返回的内容:

     "172.17.0.3:8300"

    复制代码

    172.17.0.3 就是 node2 节点的 IP

    使用

    部署完了,那么可以看看怎么用这个东东了。

    注册个服务

    使用 HTTP API 注册个服务,使用[接口 API](
    https://www.consul.io/api/agent/service.html API)调用

    调用 
    http://consul:8500/v1/agent/service/register PUT 注册一个服务。request body:

    1. {
    2. "ID": "userServiceId", //服务id
    3. "Name": "userService", //服务名
    4. "Tags": [ //服务的tag,自定义,可以根据这个tag来区分同一个服务名的服务
    5. "primary",
    6. "v1"
    7. ],
    8. "Address": "127.0.0.1",//服务注册到consul的IP,服务发现,发现的就是这个IP
    9. "Port": 8000, //服务注册consul的PORT,发现的就是这个PORT
    10. "EnableTagOverride": false,
    11. "Check": { //健康检查部分
    12. "DeregisterCriticalServiceAfter": "90m",
    13. "HTTP": "http://www.baidu.com", //指定健康检查的URL,调用后只要返回20X,consul都认为是健康的
    14. "Interval": "10s" //健康检查间隔时间,每隔10s,调用一次上面的URL
    15. }
    16. }

    复制代码

    使用 curl 调用:

    1. curl http://172.17.0.4:8500/v1/agent/service/register -X PUT -i -H "Content-Type:application/json" -d '{
    2. "ID": "userServiceId",
    3. "Name": "userService",
    4. "Tags": [
    5. "primary",
    6. "v1"
    7. ],
    8. "Address": "127.0.0.1",
    9. "Port": 8000,
    10. "EnableTagOverride": false,
    11. "Check": {
    12. "DeregisterCriticalServiceAfter": "90m",
    13. "HTTP": "http://www.baidu.com",
    14. "Interval": "10s"
    15. }
    16. }'

    复制代码

    OK,这里成功注册了一个服务

    发现个服务

    刚刚注册了名为 userService 的服务,我们现在发现(查询)下这个服务

    curl http://172.17.0.4:8500/v1/catalog/service/userService

    返回的响应:

    1. [
    2. {
    3. "Address": "172.17.0.4",
    4. "CreateIndex": 880,
    5. "ID": "e6e9a8cb-c47e-4be9-b13e-a24a1582e825",
    6. "ModifyIndex": 880,
    7. "Node": "node3",
    8. "NodeMeta": {},
    9. "ServiceAddress": "127.0.0.1",
    10. "ServiceEnableTagOverride": false,
    11. "ServiceID": "userServiceId",
    12. "ServiceName": "userService",
    13. "ServicePort": 8000,
    14. "ServiceTags": [
    15. "primary",
    16. "v1"
    17. ],
    18. "TaggedAddresses": {
    19. "lan": "172.17.0.4",
    20. "wan": "172.17.0.4"
    21. }
    22. }
    23. ]

    复制代码

    内容有了吧,这个就是我们刚刚注册的服务的信息,就可以获取到

    服务的名称是“userService”

    服务地址是“127.0.0.1”

    服务的端口是“8000”

    存储个 K/V

    设置一个值到 user/config/connections 内容为 5

    docker exec -t node1 consul kv put user/config/connections 5

    复制代码

    获取特定的值

    docker exec -t node1 consul kv get -detailed user/config/connections

    复制代码

    值的内容为 5,还有 key 等相关的值

    总结

    服务发现以及配置共享的简单样例展示了下,详细的使用还是需要看官方文档,这里只是列举了一些样例,用于理解和简单的使用 consul。

  • 相关阅读:
    数据结构第5章课后习题答案
    leetcode竞赛:20220904双周赛
    【Linux】tail命令使用
    Vue+OpenLayers 创建地图并显示鼠标所在经纬度
    机器学习之决策树【西瓜书】
    如何发高质量的外链?
    linux硬件信息及性能基础运维命令
    数组与链表
    Flutter:Android/iOS集成Flutter模块
    django DRF认证组件
  • 原文地址:https://blog.csdn.net/l688899886/article/details/125524564