文档章节

consul简介

Feng_Yu
 Feng_Yu
发布于 2016/05/16 12:58
字数 3190
阅读 2896
收藏 35

consul简介

这篇文档简单介绍一下consul这款软件的功能以及原理。

注: 本篇博客主要介绍简单的功能使用,在本地环境快速搭建起运行环境。如果要在产品环境部署,请参考这篇文章: https://www.digitalocean.com/community/tutorials/how-to-configure-consul-in-a-production-environment-on-ubuntu-14-04

HashiCorp的CTO在infoq上有一个分享,ppt在此(需爬墙): http://www.slideshare.net/InfoQ/consul-serviceoriented-at-scale 。极具参考价值。介绍了consul的用例,以及设计思想等等,强烈推荐一阅。看过这篇ppt以及下面的访谈记录,再看consul的文档就十分清晰了

consul是什么

consul是HashiCorp公司推出的一款开源工具,用于实现分布式系统的服务发现与配置。与其他类似产品相比,提供更“一站式”的解决方案。consul内置有KV存储,服务注册/发现,健康检查,HTTP+DNS API,Web UI等多种功能。

HashiCorp官方公布的一张consul的架构图如下:

consul的优势

  • 使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft.
  • 支持多数据中心,内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等. zookeeper 和 etcd 均不提供多数据中心功能的支持.
  • 支持健康检查. etcd 不提供此功能.
  • 支持 http 和 dns 协议接口. zookeeper 的集成较为复杂, etcd 只支持 http 协议.
  • 官方提供web管理界面, etcd 无此功能.

与其他同类型的产品详细对比,官方有一个比较详尽的文档: https://www.consul.io/intro/vs/zookeeper.html

简单来说,相比zookeeper,consul要更轻量,依赖轻(Go VS Java),Raft算法要比Paxos算法简单的多,而且效率高。

相比etcd,提供了更多的功能,比如DNS server,多数据中心同步,WebUI等等。

consul的简单使用

consul的使用非常简单,采用Go语言编写,编译出的文件无其他依赖。因此只需要从官方下载编译好的二进制可执行程序直接运行就可以了。

# consul
usage: consul [--version] [--help] <command> [<args>]

Available commands are:
    agent          Runs a Consul agent
    configtest     Validate config file
    event          Fire a new event
    exec           Executes a command on Consul nodes
    force-leave    Forces a member of the cluster to enter the "left" state
    info           Provides debugging information for operators
    join           Tell Consul agent to join cluster
    keygen         Generates a new encryption key
    keyring        Manages gossip layer encryption keys
    leave          Gracefully leaves the Consul cluster and shuts down
    lock           Execute a command holding a lock
    maint          Controls node or service maintenance mode
    members        Lists the members of a Consul cluster
    monitor        Stream logs from a Consul agent
    reload         Triggers the agent to reload configuration files
    rtt            Estimates network round trip time between nodes
    version        Prints the Consul version
    watch          Watch for changes in Consul

consul的运行方式

consul以agent形式运行。agent有两种模式: serverclient

server的作用是提供一致性的保证,存储着Raft信息。几乎可以认为server是数据存储中心,绝大多数的运行数据都保存在server。每个数据中心至少要保证一个server节点。官方建议每个数据中心保持3,5或7个server节点,以保证高可用。以server方式运行:

consul agent -server -data-dir /tmp/consul

client就比server轻量的多,基本上只提供和server交互的接口,作为访问server的代理。以client方式运行:

# 去掉-server参数就是client模式,并且要join到一个cluster中。
# 也可以使用consul join命令手工加入到一个集群中
consul agent -data-dir /tmp/consul -join X.X.X.X  

以下功能演示均需要有server节点,因此使用以下命令启动server:

consul agent -server -ui -bootstrap -client=0.0.0.0 -data-dir /tmp/consul

加上-ui参数可以启用内置的WebUI,使用浏览器访问http://localhost:8500即可打开这个WebUI。

服务注册

服务需要先进行注册,才能实现健康检查,服务发现等这些功能。

服务注册的方法有两种,一种是写到配置文件中,启动时加载。另一种是在consul启动之后通过HTTP API动态添加。

服务注册的方法相当简单,写一个json配置文件,定义服务名即可,以定义一个rtds服务为例:

{
  "service": {
    "name": "rtds"
  }
}

保存为rtds.json,然后重启consul并加载这个配置文件:

consul agent -server -ui -bootstrap -client=0.0.0.0 -data-dir /tmp/consul -config-file rtds.json

打开webui(8500端口)就可以看到这个service了。也可以通过HTTP API列出这个service:

$ curl 172.16.250.11:8500/v1/agent/services?pretty
{
    "consul": {
        "ID": "consul",
        "Service": "consul",
        "Tags": [],
        "Address": "",
        "Port": 8300,
        "EnableTagOverride": false,
        "CreateIndex": 0,
        "ModifyIndex": 0
    },
    "rtds": {
        "ID": "rtds",
        "Service": "rtds",
        "Tags": null,
        "Address": "",
        "Port": 0,
        "EnableTagOverride": false,
        "CreateIndex": 0,
        "ModifyIndex": 0
    }
}

服务动态注册的方式,向HTTP API发起PUT请求注册新服务,body部分和json配置文件格式一致:

$ curl 172.16.250.11:8500/v1/agent/services?pretty
{
    "consul": {
        "ID": "consul",
        "Service": "consul",
        "Tags": [],
        "Address": "",
        "Port": 8300,
        "EnableTagOverride": false,
        "CreateIndex": 0,
        "ModifyIndex": 0
    }
}

$ curl -XPUT -d '{"name":"rtds"}' 172.16.250.11:8500/v1/agent/service/register
$ curl 172.16.250.11:8500/v1/agent/services?pretty
{
    "consul": {
        "ID": "consul",
        "Service": "consul",
        "Tags": [],
        "Address": "",
        "Port": 8300,
        "EnableTagOverride": false,
        "CreateIndex": 0,
        "ModifyIndex": 0
    },
    "rtds": {
        "ID": "rtds",
        "Service": "rtds",
        "Tags": null,
        "Address": "",
        "Port": 0,
        "EnableTagOverride": false,
        "CreateIndex": 0,
        "ModifyIndex": 0
    }
}

服务发现

consul对服务发现提供两种接口: HTTP API和DNS查询。

先看下HTTP API。列出已注册的服务GET请求/v1/catalog/services即可列出。追加?dc=<dc_name>可以列出指定数据中心的注册服务。 用GET请求/v1/catalog/service/<service_name>即可列出注册此服务的全部节点信息,同样可以追加?dc=参数:

$ curl 172.16.250.11:8500/v1/catalog/service/rtds?pretty
[
    {
        "Node": "shifudaotest",
        "Address": "172.16.250.11",
        "ServiceID": "rtds",
        "ServiceName": "rtds",
        "ServiceTags": [],
        "ServiceAddress": "",
        "ServicePort": 0,
        "ServiceEnableTagOverride": false,
        "CreateIndex": 276,
        "ModifyIndex": 277
    }
]

DNS API: consul会占用一个DNS服务器端口8600,提供DNS查询服务。每一个注册的服务,会在consul提供一条NAME.service.consul的解析记录。用DNS查询工具就可以进行查询:

$ dig @172.16.250.11 -p 8600 rtds.service.consul        # 使用dig工具查询rtds.service.consul解析记录

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> @172.16.250.11 -p 8600 rtds.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20558
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;rtds.service.consul.		IN	A

;; ANSWER SECTION:
rtds.service.consul.	0	IN	A	172.16.250.11

;; Query time: 47 msec
;; SERVER: 172.16.250.11#8600(172.16.250.11)
;; WHEN: Fri May 06 20:13:58 CST 2016
;; MSG SIZE  rcvd: 72

可以看到rtds.service.consul有一条A记录,指向172.16.250.11。

现在把rtds服务注销掉。可以看到rtds.service.consul已经没有任何解析记录了。

$ curl 172.16.250.11:8500/v1/agent/service/deregister/rtds  # 将rtds服务注销
$ dig @172.16.250.11 -p 8600 rtds.service.consul          

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> @172.16.250.11 -p 8600 rtds.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 62263
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;rtds.service.consul.		IN	A

;; AUTHORITY SECTION:
consul.			0	IN	SOA	ns.consul. postmaster.consul. 1462537218 3600 600 86400 0

;; Query time: 5 msec
;; SERVER: 172.16.250.11#8600(172.16.250.11)
;; WHEN: Fri May 06 20:21:05 CST 2016
;; MSG SIZE  rcvd: 105

健康检查

consul对注册的服务都支持健康检查。方法是在service下面再嵌套一个check配置即可。

{
  "service": {
    "name": "service_name",
    "check": {

    }
  }
}

consul支持5种check方式:

  • Script + Interval: 周期性运行某个可执行程序,根据程序退出码确定服务是否存活
  • HTTP + Interval: 周期性访问某个http地址,根据返回码是否为2xx确定服务是否存活。429将警告
  • TCP + Interval: 周期性发起TCP请求,根据是否成功建立连接TCP连接确定服务是否存活
  • Time to Live (TTL): 类似于心跳检测。服务状态是用过周期性向HTTP接口发起PUT请求确定的。超期没有更新数据就判断服务挂了
  • Docker + Interval: 通过docker的api检测docker内服务的状态

如果某个服务需要检测多项,可以使用checks配置:

{
  "checks": [
    {
      "id": "chk1",
      "name": "mem",
      "script": "/bin/check_mem",
      "interval": "5s"
    },
    {
      "id": "chk2",
      "name": "/health",
      "http": "http://localhost:5000/health",
      "interval": "15s"
    },
    {
      "id": "chk3",
      "name": "cpu",
      "script": "/bin/check_cpu",
      "interval": "10s"
    },
    ...
  ]
}

比如rtds会监听TCP 3130端口,我们通过周期检测3130端口的存活性判断rtds的存活,继续修改rtds.json如下:

{
  "service": {
    "name": "rtds",
    "check": {
      "name": "rtds TCP on port 3130",
      "tcp": "localhost:3130",
      "interval": "10s",
      "timeout": "1s"
    }
  }
}

使用以下命令重启consul,加载rtds.json配置:

consul agent -server -ui -bootstrap -client=0.0.0.0 -data-dir /tmp/consul -config-file rtds.json

也可以像服务注册那样,不使用配置文件,启动之后通过HTTP API添加服务与健康检测策略。操作方法完全一样,这里不做演示。

rtds未启动时:

$ curl 172.16.250.11:8500/v1/health/checks/rtds?pretty
[
    {
        "Node": "shifudaotest",
        "CheckID": "service:rtds",
        "Name": "Service 'rtds' check",
        "Status": "critical",  # 服务未启动,所以状态显示此服务挂了
        "Notes": "",
        "Output": "",
        "ServiceID": "rtds",
        "ServiceName": "rtds",
        "CreateIndex": 444,
        "ModifyIndex": 462
    }
]

$ nslookup -port=8600 rtds.service.consul 172.16.250.11  # nslookup也是一个dns测试工具
Server:		172.16.250.11
Address:	172.16.250.11#8600

# 服务挂了,所以没有rtds.service.consul的解析记录

启动rtds,等上10秒(配置的检测周期为10秒):

$ curl 172.16.250.11:8500/v1/health/checks/rtds?pretty
[
    {
        "Node": "shifudaotest",
        "CheckID": "service:rtds",
        "Name": "Service 'rtds' check",
        "Status": "passing",    # 3130端口可以成功建立TCP连接,于是passing了
        "Notes": "",
        "Output": "TCP connect localhost:3130: Success",
        "ServiceID": "rtds",
        "ServiceName": "rtds",
        "CreateIndex": 444,
        "ModifyIndex": 499
    }
]

$ nslookup -port=8600 rtds.service.consul 172.16.250.11
Server:		172.16.250.11
Address:	172.16.250.11#8600

Name:	rtds.service.consul
Address: 172.16.250.11

KV存储

这个功能就没太多要说明的了,基本用法就跟redis的用法差不多。

KV的API路径是/v1/kv/<key>,支持GET,PUT,DELETE三种请求。如果key最后跟一个/,代表创建一级目录。

$ curl -X PUT -d 'test' http://localhost:8500/v1/kv/web/key1
true
$ curl -X PUT -d 'test' http://localhost:8500/v1/kv/web/key2?flags=42
true
$ curl -X PUT -d 'test'  http://localhost:8500/v1/kv/web/sub/key3
true
$ curl http://localhost:8500/v1/kv/?recurse
[{"CreateIndex":97,"ModifyIndex":97,"Key":"web/key1","Flags":0,"Value":"dGVzdA=="},
 {"CreateIndex":98,"ModifyIndex":98,"Key":"web/key2","Flags":42,"Value":"dGVzdA=="},
 {"CreateIndex":99,"ModifyIndex":99,"Key":"web/sub/key3","Flags":0,"Value":"dGVzdA=="}]

需要注意的consul返回的value是base64编码,官方的解释是为了防止出现非UTF-8字符,所以统一编码成base64。第二个范例追加了一个flags参数,这个flags并非是由consul内部使用,而是提供给客户端的保留字段,客户端可以自定义其他含义。 如果追加?raw参数,将直接返回未经base64编码的Value值。

此外,consul的KV存储还支持Check-And-Set操作(当ModifyIndex匹配时才进行修改键值)。详情参考官方文档: https://www.consul.io/intro/getting-started/kv.html

ACL

consul提供访问控制列表(Access Control List)功能,通过ACL可以实现权限控制。consul的ACL是Capability-based security(能力基础安全)。

也就是这种ACL是每一级路径都可以而配置单独权限,默认策略是子权限继承父权限。比如/kv/key/的权限是deny,那么/kv/key/sub1这样的路径无法访问。如果再追加一条规则/kv/key/sub2的权限是read,那么/kv/key/sub2/key这样的key有只读权限,其余的key均无法访问。通过带上?token=参数验证ACL权限,ACL配置是针对每个token的。如果不带token参数,则默认anonymous

启用ACL只能在配置文件中指定。创建一个config.json文件,写入以下内容:

{
  "acl_datacenter": "dc1",
  "acl_default_policy": "deny",
  "acl_master_token": "master"
}

dc1这个数据中心(默认的数据中心)启动ACL,默认的ACL规则是deny(即不指定权限时,默认为deny),拥有管理权限的token是master

加载这个配置启动consul agent:

consul agent -server -ui -bootstrap -client=0.0.0.0 -data-dir /tmp/consul -config-file config.json

现在再请求kv,发现会返回404:

curl -v '172.16.250.11:8500/v1/kv/?recurse'  # -v参数可以看到返回码是404

带上master token再请求这个API,就没问题:

$ curl '172.16.250.11:8500/v1/kv/?token=master&recurse'
[{"LockIndex":0,"Key":"web/key1","Flags":0,"Value":"bW9kaWZpZWQ=","CreateIndex":633,"ModifyIndex":634}]

现在创建一个token mytoken,对kv/web/有只读权限,对service/rtds有读写权限,可以这么做:

$ curl -XPUT -d @- '172.16.250.11:8500/v1/acl/create?token=master' <<EOF
{
  "Type": "client",
  "Name": "mytoken",
  "Rules": "service \"rtds\" {\n policy = \"write\"\n }\n key \"web/\" {\n policy = \"read\"\n }"
}
EOF
{"ID":"1f8799ce-6f45-427c-f8e6-3878f9eda582"}

consul会返回一个ID: 1f8799ce-6f45-427c-f8e6-3878f9eda582。将这个值作为token参数传递给HTTP API就拥有了对应的权限。

$ curl '172.16.250.11:8500/v1/kv/?recurse&token=1f8799ce-6f45-427c-f8e6-3878f9eda582&pretty'
[
    {
        "LockIndex": 0,
        "Key": "web/key1",
        "Flags": 0,
        "Value": "bW9kaWZpZWQ=",
        "CreateIndex": 633,
        "ModifyIndex": 634
    }
]

可以看到带上这个token以后,就可以读取web/key1的值了,而之前是404。

其他功能

以上几个功能都是WebUI上可以可视化操作的功能,是最常见的功能。其他还有一些只能用API操作的功能。比如consul exec直接调用RPC接口,而非HTTP接口。consul event向消息总线发送自定义消息。consul watch监听消息总线异步响应,甚至还支持分布式锁等等。这些功能可以详细参考官方文档,用到的时候再查阅官方文档。

© 著作权归作者所有

共有 人打赏支持
Feng_Yu
粉丝 158
博文 38
码字总数 45571
作品 0
西安
运维
私信 提问
加载中

评论(2)

Feng_Yu
Feng_Yu

引用来自“相见欢”的评论

排版很漂亮,是用MarkDown写的吗?
自从osc的blog支持markdown就一直在用了。
相见欢
相见欢
排版很漂亮,是用MarkDown写的吗?
史上最简单的 SpringCloud 教程 | 第十四篇: 服务注册(consul)

转载请标明出处: http://blog.csdn.net/forezp/article/details/70245644 本文出自方志朋的博客 这篇文章主要介绍 spring cloud consul 组件,它是一个提供服务发现和配置的工具。consul具有...

forezp
2017/04/19
0
0
Consul 简介、安装、常用命令的使用

1 Consul简介 Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul的方案更“一站式”,内置了服务注册与发现框 架、分...

我有药
2018/06/29
0
0
第1章 consul简介

1、consul的作用 服务发现 Consul clients提供服务(例如API) 其他的client发现服务的提供者(通过DNS或http,应用可以轻松的发现他们所依赖的服务) 健康检查 Key-Value存储操作 动态配置 ...

xwlan
2017/11/17
0
0
spring-cloud1:服务注册与发现

spring-cloud1:服务注册与发现 www.blogways.net2017-12-172 阅读 spring服务 目 录 1 spring cloud简介 2 微服务架构 3 服务注册与发现 一、spring cloud简介 Spring Cloud是一个基于Sprin...

www.blogways.net
2017/12/17
0
0
Spring Cloud Finchley.SR1 的学习与应用 2 - Consul

Spring Cloud Consul 简介 consul是google开源的一个使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方...

张shieppp
2018/11/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

搜索引擎(Solr-索引详解)

时间字段类型特别说明 Solr中提供的时间字段类型( DatePointField, DateRangeField,废除的TrieDateField )是以时间毫秒数来存储时间的。 要求字段值以ISO-8601标准格式来表示时间:YYYY-MM...

这很耳东先生
21分钟前
0
0
Java成神之路

1、基础篇 01、面向对象 → 什么是面向对象 面向对象、面向过程 面向对象的三大基本特征和五大基本原则 → 平台无关性 Java 如何实现的平台无关 JVM 还支持哪些语言(Kotlin、Groovy、JRuby...

asdf08442a
51分钟前
2
0
dubbo源码分析-服务导出

简介 dubbo框架spring Schema扩展机制与Spring集成,在spring初始化时候加载dubbo的配置类。 dubbo服务导出的入口类是ServiceBean的onApplicationEvent方法 ServiceBean的继承关系如下 publ...

王桥修道院副院长
57分钟前
0
0
QQ音乐的动效歌词是如何实践的?

本文由云+社区发表 作者:QQ音乐技术团队 一、 背景 1. 现状 歌词浏览已经成为音乐app的标配,展示和动画效果也基本上大同小异,主要是单行的逐字染色的卡拉OK效果和多行的滚动效果。当然,我...

腾讯云加社区
57分钟前
4
0
idea里配置springboot项目打热部署

首先添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional></dependency> 然后添......

shatian
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部