一. Consul的介绍
1.1 什么是Consul
图 - Consul的Logo
“Consul is a service networking solution to connect and secure services across any runtime platform and public or private cloud.” 这句是官网[1]给的定义。当然!它是开源的。
图 - HashiCorp公司Logo
在官网上笔者发现了HashiCorp的公司Logo。由于是第一次看知道这个公司,特意百度了一下[2]:HashiCorp是由Mitchell Hashimoto和Armon Dadgar联合创办,总部位于美国旧金山,致力于为企业提供服务,通过数据中心管理技术研发,让开发者通过工具构建完整的开发环境,提高开发效率。公司所提供的主要企业服务包括应用程序开发、交付和维护,使用的DevOps 基础设施工具主要包括Vagrant、Packer 、 Terraform 、Serf 、Consul , Vault 和 Nomad 等。根据18年的新闻[3],公司估值19亿美元。
Consul 使用 Go 语言编写,因此具有天然可移植性,安装的时候只有一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。[5]
1.2 Consul的角色
agent: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群。
server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯。每个数据中心的 server 数量推荐为 3 个或是 5 个。
Consul 使用 Go 语言编写,因此具有天然可移植性,安装的时候只有一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。[5]
二. Consul集群部署
2.1 在ubuntu上部署Consul
(1)下载Consul软件包(本文使用的Consul版本为1.5.1),解压缩[6]
(2)上传至各台机器
(3)mv consul /usr/local/bin
(4)配置如下环境变量/etc/profile
export CONSUL_HOME=/usr/local/bin/consul
export PATH=$PATH:CONSUL_HOME
source /etc/profile # 使配置生效
2.2 启动server
启动第一个server:
consul agent -server -ui -bootstrap-expect=3 -data-dir=/data/consul -node=agent-1 -client=0.0.0.0 -bind=IP-1 -datacenter=dc1
启动第二个server:
consul agent -server -ui -bootstrap-expect=3 -data-dir=/data/consul -node=agent-2 -client=0.0.0.0 -bind=IP-2 -datacenter=dc1 -join IP-1
参数解释:
bootstrap-expect:集群期望的节点数,只有节点数量达到这个值才会选举leader。
server:运行在server模式
data-dir:指定数据目录,其他的节点对于这个目录必须有读的权限
node:指定节点的名称
bind:为该节点绑定一个地址
config-dir:指定配置文件,定义服务的,默认所有.json结尾的文件都会读
enable-script-checks=true:设置检查服务为可用
datacenter: 数据中心没名称,
join:加入到已有的集群中
2.3 启动agent
consul agent -data-dir=/data/consul -node=agent-4 -client=0.0.0.0 -bind=IP -datacenter=dc1 -join IP-1
2.4 查看集群的各个节点
consul members:
图 - consul members 命令行示意图
图 - Consul节点UI示意图
三. 有了Consul能做什么?
1. 服务注册和服务发现
2. 健康检查
3. 统一配置中心
3.1 服务注册和服务发现
“注册”这个词让笔者马上想到的是“新生注册”,根据百度汉语释义:“把名字记入簿册”;所以可以将服务注册看作“把服务信息存储到某个地方”的过程。如果这个地方是数据库,那注册不就是“Insert”嘛。而服务发现其实就是一次将服务名称作为查询条件的“Query”。
为什么需要服务注册和发现呢?
图 - 一种常见的架构
上图最常见的架构之一。以NGINX为例,在NGINX的配置文件中写入{serviceB1,serviceB2...}的IP,端口等信息,{serviceC/frontend/...}只需要“知道”NGINX的地址而不用关心它调用服务的信息。
该架构的问题在于:
(1)当性能不足需要增加实例时,NGINX需要修改配置文件并reload。
(2)当{serviceB,...}中有某些实例“挂了”,NGINX并不能“察觉”,仍然会有Request被分发到这些服务上,这些Request显然不能被正常处理。
问题(1)中“修改配置文件并reload”的过程其实可以立即为“注册和发现”的过程,显然这会增加运维的负担。“DRP”是一个很多人都知道的原则,一个很好的提升效率的方式就是避免重复劳动,所以需要将“注册和发现”过程抽象为一个服务,让程序自动完成这些工作。能完成“注册和发现”任务的服务需要有哪些特点呢?我们先给这个服务命名为ServiceCenter。
由于所有的服务数据都会在ServiceCenter,所以它必须是分布式,高可用的。
几乎都有的服务都会对并发有要求,所以ServiceCenter不能成为并发的“瓶颈”。
业界常用的服务注册与服务发现工具有 ZooKeeper、etcd、Consul 和 Eureka等,这些工具基本都符合上述两个特点。
图 - 服务注册,服务发现和健康检查的一般架构
图-Consul的服务注册展示页面
3.2 健康检查(Health Check)
只有服务注册和服务发现还是没办法解决前文的问题(2),注册只能保证“一段时间”内服务是可用的。好比:在外地工作需要办居住证,隔一段时间就需要年审,年审之后居住证才能继续生效,在现实生活中,这个时效一般是一年。但在计算机的世界里,对服务的“年审”一般是秒级的,通过的做法是定时(eg.每5s)像服务实例发送HTTP请求,服务如果返回正确的信息(eg.HTTP状态码为200)则“年审”通过,否则判定服务实例出现异常,需要将该实例下线(从数据库的角度就是Update或者Delete操作),Request不再发送到该实例。
图 - Consul健康检查
3.3 统一配置中心
配置文件是编程中绕不开的一部分。简单的代码或者写得糙一些,配置可能直接写死在代码里了,当涉及到复杂的项目,配置往往冗长,而且项目可能部署为多个实例(instance),所以配置的修改就会成为一个问题,所以需要统一配置中心。统一配置的方式没有定法,本质也是一个服务。所有的其它服务都需要去从这个服务读取配置,这就要求:
(1)决不能有单点故障问题,分布式几乎是唯一选择;
(2)需要能够支撑高并发。其实mysql,redis等等已经可以满足上述两点了,但是为什么不?配置文件相对于业务数据来说占用的空间实在是太小了,笔者认为没有必要用专门的数据库工具来解决这个问题。
Consul已经可以在实践中帮助我们解决服务注册和发现的问题,又可以成为我们的统一配置中心,实在是一个非常nice的工具。
图 - Consul kv配置中心的UI
四. Consul的特点
(1)Consul的功能非常完整,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案[5]
(2)一般,服务向本机所在Consul agent进行注册,该agent将服务数据同步到server集群,并且由该agent对服务进行健康检查,其它agent和server集群并不参与对该agent的健康检查,所以当agent“挂了”之后,由该agent注册的所有服务会不可用,其它agent和server集群也不会对这些服务进行“接管”;当然agent“挂了”的概率会远远小于服务崩溃的概率。
图 - Consul服务注册,发现与健康检查架构图
(3)与其他类似工具的比较,可参考[5],有时间以后再谈。
Reference
[1]Consul官网
[2]HashiCorp百度百科
[3]投资者将HashiCorp作为下一个值得关注的初创公司
[4]百度汉语-注册
[5]Eureka 2.X停止开发,注册中心Consul使用详解
[6]Consul初探-从安装到运行