服务发现系统consul介绍

来源:互联网 发布:数据库一致性 cap 编辑:程序博客网 时间:2024/06/07 15:15

最近在折腾服务发现这个功能,偶然发现了consul,发现国内资料很少(包括etcd),看了官方文档后,发现很厉害啊,consul是一个用来配置服务发现的工具,consul是分布式的、高可用、横向扩展的。consul提供的一些关键特性:

service discovery:consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易,一些外部服务,例如saas提供的也可以一样注册。

health checking:健康检测使consul可以快速的告警在集群中的操作。和服务发现的集成,可以防止服务转发到故障的服务上面。

key/value storage:一个用来存储动态配置的系统。提供简单的HTTP接口,可以在任何地方操作。

multi-datacenter:无需复杂的配置,即可支持任意数量的区域。

下面初步的讲解一下consul的特性: 

1    install consul

        我的机器是ubuntu14.04系统, 先下载consul软件包,consul官网已经有编译好的二进制包,支持各种平台:win、linux等等,下载符合你平台的软件包: 在这里 , 下载包: 0.4.1_linux_amd64.zip。解压完毕后只有一个consul文件。

2    run agent

consul安装完毕后,agent就可以启动了,agent可以运行在server或者client模式,每个数据中心至少有一个agent运行在server模式,一般建议是3或者5个server。部署单个server是非常不好的,因为在失败场景中出现数据丢失是不可避免的。本文涵盖的是创建一个新的数据中心,所有其他的agents都运行在client模式,这是一个非常轻量级的服务注册进程,它会运行健康监测,并将查询结果转发到服务。agent必须运行在集群中的每一个节点上。 

我们先运行一个agent在server模式: 

./consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul

正如你看到的一样,consul agent已经启动了,并且打印了一些日志到终端上,从日志中可以看到我们的agent已经运行在server模式了,并且已经是整个集群的领导节点。而且,本地成员已经被标记为集群中的健康成员了。这时候你在另一个终端中运行consul members就可以看到整个集群中的成员了。这时候你只能看到你自己,因为我们的集群中还没加入其他成员。 

输出已经显示了你自己的节点信息,有地址信息、健康状况、在集群中的角色、以及一些版本信息,如果要查看一些metadata,则可以加入-detailed标记 

consul members命令输出的信息是基于gossip协议产生的,并且最终一致的。也可以使用HTTP API来查看整个集群的强一致性视图信息。 

除了使用HTTP API接口可以查看集群的视图信息外,也可以使用DNS接口来查看,要在你的节点名称后面加上node.consul字符串。 

    停止agent服务,在第一个终端中,你可以使用ctrl-c来优雅的停止agent,如果你停止的是client,当你优雅的离开后,consul会通知集群中的其他成员你这个节点以及处于left状态。如果你是强制killed掉agent,集群中的其他成员会认为你是failed了。当成员leaves后,该成员的services和checks会从catalog被移除,当成员fails后,该成员的健康状态会被简单的标记为critical,但是不会从catalog删除。consul会自动的尝试链接failed的节点,这样允许节点在某些网络状况中恢复,如果节点是left状态,则不会再联系该节点。

3    service

前面两节我们启动了第一个agent,并查看了集群中的成员,利用HTTP API查询了一些节点信息,在这一节,我们会注册我们的第一个服务,并查询该服务。 

服务定义:一个服务可以通过提供 服务定义配置文件 或者通过调用 HTTP API 来注册。我们先通过配置服务定义配置文件来注册新服务,这是最普通的服务注册方法,首先为consul创建一个配置文件目录,按照linux的风格,一般建立在/etc/consul.d目录下,consul会加载在该目录下的所有文件(以json结尾),接着我们定义一个服务定义配置文件,我们这个要注册的服务是提供web服务的,运行在80端口,会给该服务打一些tag,因此这个配置文件就命名为web.json。配置完成后,我们再次重新启动agent,并在命令行提供配置文件目录。 

mkdir /etc/consul.decho '{"service": {"name": "web", "tags": ["rails"], "port": 80}}' >/etc/consul.d/web.json./consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -config-dir /etc/consul.d

 

你会注意到输出的日志中,最后有一行显示已经synced service web了,这表示已经从配置文件中加载了相关信息。如果你想注册多个服务,则可以创建多个配置文件。 

服务查询:一旦agent启动后,并且服务已经同步,我们就可以使用DNS或者HTTP API来进行查询了。我们首先使用DNS来查询,在使用DNS查询时,services的名称是name.service.consul,所有的DNS names都在consul空间下面(consul空间是可以修改的),service关键字是告诉consul我们在查询services,name则是service的名称,我们的web服务注册后,我们则可以使用下面的名称进行查询:web.service.consul 

你可以看到一个A记录,记录了服务可达的ip地址,A记录只能显示ip地址,你也可以使用DNS API来检索ip/port,只需要添加SRV记录即可: 

SRV记录的返回结果说明web服务运行在Docker-3.node.dc1.consul节点的80端口上面,另外,我们也可是使用DNS API过滤出只符合tag标记的sevice,可以在dns查询时使用如下格式:tag.name.service.consul,tag则是你想过滤的tag。

下面我们使用HTTP API接口来查询一下服务: 

curl -s http://localhost:8500/v1/catalog/service/web | python -m json.tool

 

服务升级:服务定义的升级可以通过先修改服务定义配置文件,然后给agent发送一个SIGHUP信号即可,这样允许你在升级服务时,而不会产生agent宕机时间或者服务不可达。或者通过HTTP API接口来动态的增加、删除、修改服务。 

4    consul cluster

现在我们已经启动了第一个agent,注册了第一个服务,并用API接口做了一些查询,这已经显示了consul的易用性,但是我们还不知道要怎么横向扩展consul,在这一节我们创建一个多成员的集群。当你启动一个consul agent的时候,agent一开始并不知道其他节点,agent是集群中一个孤立的点,为了知道集群中的其他成员,agent必须加入一个集群中,加入一个集群后,agent会很快知道该集群中的其他成员,一个agent可以加入其他agent,它也不必运行在server模式。为了模拟真实的集群,我使用三台ubuntu14.04构建一个consul集群,机器信息如下: 

192.168.1.100  Docker-1  server192.168.1.101  Docker-2  client192.168.1.102  Docker-3  client

我门先在第一台机器上启动agent,以server模式运行,并且指定一个node名称,一般以主机名为node名称,这个名称要唯一。我们同时提供要监听的地址,server的这个地址对于集群中的其他agent必须是可达的,下面我们启动: 

./consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node=Docker-1 -bind=192.168.1.100

在100上的server模式的agent启动后,我们来到101上启动我们的第二个agent,这个agent绑定101节点的ip地址。下面我们启动101上的节点, 

./consul agent -data-dir /tmp/consul -node=Docker-2 -bind=192.168.1.101

 

101上的节点启动后,可以看到101在报错,之前说过一个集群中至少要有一个server agent,101启动的时候没有设置server模式,这时候就相当于101在它自己的集群中,但是该集群中没有server,只有一个client,我们有两个agent在运行,一个server模式,一个client模式,但是这两个节点彼此都互不知道,它们都运行在自己的集群中,你可以通过consul members来查看,我们下面就要把101的client加入到server的集群中。 在100的server上面,通知101的agent加入server集群。 这时候应该在agent的输出log上看到一些信息,这时候再执行consul members就会看到整个集群的成员了。 

先看101的agent增加了哪些日志 

可以看到该agent加入Docker-1的集群中了,Docker-1是集群的leader,再看看Docker-1的agent有哪些日志输出 

agent Docker-2加入进来了,并标记Docker-2的状态为alive。 

有个快捷的方法,在agent启动时就可以直接加入集群,在consul agent启动的时候使用-join参数,即可把agent加入集群中,我们就用这个方法把Docker-3直接加入Docker-1的集群中。 

./consul agent -data-dir /tmp/consul -node=Docker-3 -join=192.168.1.100 -bind=192.168.1.102

再来看看集群中的成员,已经加入了Docker-3 

而且集群中的成员都收到了Docker-3加入的信息,我们看看DOcker-2的agent打印出的log信息 

节点查询,就像service查询一样,consul也提供DNS和HTTP API接口来查询节点,对于DNS查询,你可以使用name.node.consul或者name.datacenter.node.consul来查询,如果datacenter被省略,则默认查询本地datacenter。 

离开集群,就像前面的方法一样,使用ctrl-c来离开集群,或者强制killed掉agent,当然这两种方法的优劣前面已经讲过了。 

5    health check

现在我们已经知道怎么运行consul、增加节点和服务、查询节点和服务、以及创建集群,这一节我们增加节点和服务间的健康监测,这是服务发现的重要组成部分,因为它要阻止访问不健康的服务。 

检测定义:就像服务定义一样,我们可以通过 检测定义配置文件 或者 HTTP API 接口来定义检测。我们定义检测配置就像配置服务定义一样,我们在Docker-2节点的consul配置目录增加两个配置文件,一个配置文件是host层面的检测,一个是server层面的检测。 

host检测,每30s检测一次 

echo '{"check": {"name": "ping", "script": "ping -c1 www.baidu.com >/dev/null", "interval": "30s"}}' >/etc/consul.d/ping.json

server检测,每10秒中检测一次。已经在Docker-2启动了apache服务 

echo '{"service": {"name": "web", "tags": ["rails"], "port": 80,  "check": {"script": "curl localhost:80 >/dev/null 2>&1", "interval": "10s"}}}' >/etc/consul.d/web.json

然后重启agent或者给当前的agent进程发送一个SIGHUP信号(kill -s SIGHUP agent_pid),因为我们在启动agent的时候并没有添加-config-dir标记,所以agent并不知道consul的配置文件目录在哪里,所以我们要ctrl-c来重启agent,并添加配置文件目录 

./consul agent -data-dir /tmp/consul -join=Docker-1 -node=Docker-2 -bind=192.168.1.101 -config-dir=/etc/consul.d

检查健康状态,我们已经添加了一些健康检测的机制,现在我们可以使用HTTP API来检测了,我们先查看所有的检测。 

curl -s http://localhost:8500/v1/health/state/any | python -m json.tool

也可以使用DNS接口来查询。 

6    K/V data

上面章节我们已经实现了服务发现和健康检测,consul也提供了一个简单的K/V存储系统,这可以用来动态获取配置、进行服务协调、主节点选举,其他开发人员能想到的build过程等等。 

为了演示怎么操作K/V系统,我们将会操作少量数据。我们在Docker-2节点上进行测试,首先要检测K/V系统中是否已经有key存在。 

curl -v http://127.0.0.1:8500/v1/kv/?recurse

可以看到目前K/V系统中并没有key,我们http返回的是404状态码,现在我们put一些数据进去: 

curl -X PUT -d 'test' http://127.0.0.1:8500/v1/kv/web/key1curl -X PUT -d 'test' http://127.0.0.1:8500/v1/kv/web/key2?flags=42curl -X PUT -d 'test' http://127.0.0.1:8500/v1/kv/web/web/sub/key3

开始查看K/V系统中的key

curl -s http://127.0.0.1:8500/v1/kv/?recurse|python -m json.tool

我们创建了三个key,每个key的value都是test,在K/V系统中值都是base64加密过的,我们给'web/key2'这个key添加了一个tag,所有的key支持64bit的整形长度,在插入完毕后,可以用?recurse来查看所有的key,你也可以只查看单个key 

curl -s http://127.0.0.1:8500/v1/kv/web/key1|python -m json.tool

删除key也是很容易的,我们可以指定全路径来删除单个key,也可以使用?recurse来删除所有key。 

curl -s http://127.0.0.1:8500/v1/kv/web/key1|python -m json.tool

可以通过给一个key赋予新值来进行update,另外,consul会执行一个Check-And-Set的操作,确保更新操作的原子性。这可以通过提供?cas=参数来实现,cas的值是ModifyIndex的值。 

curl -X PUT -d 'newval' http://127.0.0.1:8500/v1/kv/web/key1?cas=106curl -X PUT -d 'newval' http://127.0.0.1:8500/v1/kv/web/key1?cas=106curl -s http://127.0.0.1:8500/v1/kv/web/key1|python -m json.tool

在上面的情况可以看到,第一次CAS update成功了,因为上一次修改的时间是106,但是第二次CAS的操作失败了,因为ModifyIndex的大小小于106,。

7    WEB UI

consul同样也支持web界面,这个ui可以用来查看所有的服务和节点,所有的健康检测和它们当前的状态,读取设置K/V系统的值。ui默认自动支持多datacenter。这些ui是静态html和jsp文件,你不需要单独运行一个web服务器,consul agent本身可以配置一个web服务。我们在Docker-3上配置该UI服务。 

下载UI组件: WEB UI 

下载完成后是一个0.4.1_web_ui.zip压缩文件,解压后是一个dist目录。先ctrl-c掉Docker-3上的agent,然后添加-ui-dir参数和-client参数重新启动agent。 

./consul agent -data-dir /tmp/consul -node=Docker-3 -join=192.168.1.100 -bind=192.168.1.102 -ui-dir=/opt/dist -client=192.168.1.102

在浏览器中输入http://192.168.1.102:8500,即可访问UI了 

        看着很不错,有services、nodes、K/V、acl、 datacenter的管理,看起来比etcd好一些。

0 0
原创粉丝点击