1. Consul介绍
Consul是一套开源的分布式服务发现和配置管理系统,支持多数据中心分布式高可用。Consul是HashiCorp( Vagrant的创建者)开发的一个服务发现与配置项目,用Go语言开发,基于 Mozilla Public License 2.0 的协议开源。
Consul包含多个组件,但是作为一个整体,为你的基础设施提供服务发现和服务配置的工具.他提供以下关键特性:
- 服务发现
Consul的客户端可用提供一个服务,比如 api 或者mysql ,另外一些客户端可用使用Consul去发现一个指定服务的提供者.通过DNS或者HTTP应用程序可用很容易的找到他所依赖的服务。 - 健康检查
Consul客户端可用提供任意数量的健康检查,指定一个服务(比如:webserver是否返回了200 OK 状态码)或者使用本地节点(比如:内存使用是否大于90%). 这个信息可由operator用来监视集群的健康.被服务发现组件用来避免将流量发送到不健康的主机。 - Key/Value存储
应用程序可用根据自己的需要使用Consul的层级的Key/Value存储.比如动态配置,功能标记,协调,领袖选举等等,简单的HTTP API让他更易于使用。 - 多数据中心
Consul支持开箱即用的多数据中心.这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。
2. 安装
在下载页面中找到和你系统匹配的包。解压Consul zip包,复制consul二进制文件到系统PATH中包含的路径下,以确保它可以被执行。在Unix系统中,~/bin和/usr/local/bin是通常的安装路径,选择哪个依赖于你安装Consul给单个用户使用还是所有用户都可以使用。对于Windows系统,你可以安装到任意目录,不过不要忘记将安装目录加入到%PATH%中去。
2.1 验证安装
安装Consul后,通过打开新的终端回话并且输入consul是否可用来验证安装是否工作。通过执行consul你应该可以看到下面类似的输出:
$ consul
Usage: consul [--version] [--help] <command> [<args>]
Available commands are:
agent Runs a Consul agent
catalog Interact with the catalog
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
kv Interact with the key-value store
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
operator Provides cluster-level tools for Consul operators
reload Triggers the agent to reload configuration files
rtt Estimates network round trip time between nodes
snapshot Saves, restores and inspects snapshots of Consul server state
validate Validate config files/directories
version Prints the Consul version
watch Watch for changes in Consul
3. 启动Consul
3.1 开发模式运行:
$ consul agent -dev
==> Starting Consul agent...
==> Consul agent running!
Version: 'v1.0.2'
Node ID: '5231963e-3453-ac4c-cf31-d13736402df9'
Node name: 'MantouMBP.local'
Datacenter: 'dc1' (Segment: '<all>')
Server: true (Bootstrap: false)
Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, DNS: 8600)
Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false
你可以看到,Consul代理已经启动并且输出了一些日志信息。从日志信息中,你可以看到我们代理运行在服务器模式并且声明集群的leadship。另外,本地的成员已经被标记为一个健康的集群成员。
OS X用户注意:Consul使用你的机器名作为默认的节点名称。如果你的机器名包涵了点,那么DNS查询该节点会不能工作,为了避免这个问题,使用-node显式设置你的节点名称。
3.2 查看集群成员
如果你在另一个终端中运行 consul members ,你能看到Consul集群所有的节点,但是现在你只能看到一个成员(你自己的机器)
$ consul members
Node Address Status Type Build Protocol DC Segment
MantouMBP.local 127.0.0.1:8301 alive server 1.0.2 2 dc1 <all>
该命令输出显示你自己的节点,运行的地址,它的健康状态,它在集群中的角色,以及一些版本信息。另外元数据可以通过 -detailed 选项来查看。
members 命令选项的输出是基于 gossip协议 的并且其内容是最终一致。也就是说,在任何时候,你在本地代理看到的内容也许与当前服务器中的状态并不是绝对一致的。如果需要强一致性的状态信息,使用HTTP API向Consul服务器发送请求:
$ curl localhost:8500/v1/catalog/nodes
[
{
"ID": "bce12243-d825-ea69-2066-c3e3daae13fb",
"Node": "MantouMBP.local",
"Address": "127.0.0.1",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "127.0.0.1",
"wan": "127.0.0.1"
},
"Meta": {
"consul-network-segment": ""
},
"CreateIndex": 5,
"ModifyIndex": 6
}
]
另外对于HTTP API,DNS接口也常被用来查询节点信息。注意你必须确信你的DNS能够找到Consul代理的DNS服务器,Consul代理的DNS服务器默认运行在8600端口。
$ dig @127.0.0.1 -p 8600 MantouMBP.local.node.consul
; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 MantouMBP.local.node.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29410
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;MantouMBP.local.node.consul. IN A
;; ANSWER SECTION:
MantouMBP.local.node.consul. 0 IN A 127.0.0.1
;; Query time: 3 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Thu Dec 28 22:24:05 2017
;; MSG SIZE rcvd: 61
4. 使用SpringCloud Consul组件
下面我们创建提供服务的客户端,并向Consul服务注册中心注册自己。
首先,使用IDEA创建一个Spring Initializr创建一个基本的Spring Boot应用并选择Consul Dependencies:
pom.xml中,配置如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--consul中健康检查需要用到actuator,不添加会check failing-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在应用主类中通过加上@EnableDiscoveryClient注解:
@EnableDiscoveryClient
@SpringBootApplication
public class ClientServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ClientServiceApplication.class, args);
}
}
配置application.properties:
Spring Boot的配置除了可以使用传统的propertiese文件外,还支持现在被广泛推荐使用的YAML文件。YAML文件使用类似大纲的缩进形式进行表示,结构更加清晰易读。
spring.application.name=client-service
server.port=2001
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
启动工程后,访问:http://localhost:8500/ui/#/dc1/services,
可以看到下面的页面,已经成功注册了服务。
服务发现的接口DiscoveryClient是Spring Cloud对服务治理做的一层抽象,所以可以屏蔽Eureka和Consul服务治理的实现细节,我们的程序不需要做任何改变,只需要引入不同的服务治理依赖,并配置相关的配置属性就能轻松的将微服务纳入Spring Cloud的各个服务治理框架中。