自己就一台机子,所以这里就演示下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模式)
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 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:
{ "ID": "userServiceId", //服务id"Name": "userService", //服务名"Tags": [ //服务的tag,自定义,可以根据这个tag来区分同一个服务名的服务"primary", "v1" ], "Address": "127.0.0.1",//服务注册到consul的IP,服务发现,发现的就是这个IP"Port": 8000, //服务注册consul的PORT,发现的就是这个PORT"EnableTagOverride": false, "Check": { //健康检查部分"DeregisterCriticalServiceAfter": "90m", "HTTP": "http://www.baidu.com", //指定健康检查的URL,调用后只要返回20X,consul都认为是健康的"Interval": "10s"//健康检查间隔时间,每隔10s,调用一次上面的URL } }
使用curl调用:
curlhttp://172.17.0.4:8500/v1/agent/service/register -X PUT -i -H "Content-Type:application/json" -d '{"ID": "userServiceId", "Name": "userService", "Tags": [ "primary", "v1" ], "Address": "127.0.0.1", "Port": 8000, "EnableTagOverride": false, "Check": { "DeregisterCriticalServiceAfter": "90m", "HTTP": "http://www.baidu.com", "Interval": "10s" } }'
OK,这里成功注册了一个服务
发现个服务
刚刚注册了名为userService的服务,我们现在发现(查询)下这个服务
curl http://172.17.0.4:8500/v1/catalog/service/userService
返回的响应:
[ { "Address": "172.17.0.4", "CreateIndex": 880, "ID": "e6e9a8cb-c47e-4be9-b13e-a24a1582e825", "ModifyIndex": 880, "Node": "node3", "NodeMeta": {}, "ServiceAddress": "127.0.0.1", "ServiceEnableTagOverride": false, "ServiceID": "userServiceId", "ServiceName": "userService", "ServicePort": 8000, "ServiceTags": [ "primary", "v1" ], "TaggedAddresses": { "lan": "172.17.0.4", "wan": "172.17.0.4" } } ]
内容有了吧,这个就是我们刚刚注册的服务的信息,就可以获取到
服务的名称是“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。
Spring Cloud 结合consul使用
如果是使用spring cloud来使用consul,可以查看我的相关样
例:http://git.oschina.net/buxiaoxia/spring-demo
spring cloud 结合consul的使用,下一篇文章再进行描述吧
相关文档连接
CONSUL:https://www.consul.io/
CONSUL HTTP API:https://www.consul.io/api/index.html
CONSUL CLI:https://www.consul.io/docs/commands/info.html
CONSUL Health Checks:https://www.consul.io/docs/agent/checks.html