- 什么是 Consul
Consul是一种服务网格解决方案,提供具有服务发现,配置和分段功能的全功能控制平面。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全服务网格。Consul需要数据平面并支持代理和本机集成模型。Consul附带一个简单的内置代理,因此一切都可以开箱即用,但也支持第三方代理集成,如Envoy - Consul的主要特点
- 服务发现:Consul 的客户可以注册服务,例如
api
或mysql
,并且其他客户可以使用Consul来发现给定服务的提供者。使用 DNS 或 HTTP,应用程序可以轻松找到它们所依赖的服务。- 运行状况检查:Consul 客户端可以提供任意数量的运行状况检查,这些检查与给定服务(“是 Web 服务器返回 200 OK”)或本地节点(“内存利用率低于 90%”)相关联。运营商可以使用此信息来监控群集运行状况,服务发现组件使用该信息将流量路由远离不健康的主机。
- KV 商店:应用程序可以将 Consul 的分层键/值存储用于任何目的,包括动态配置,功能标记,协调,领导者选举等。简单的 HTTP API 使其易于使用。
- 安全服务通信:Consul可以为服务生成和分发 TLS 证书,以建立相互的 TLS 连接。 意图 可用于定义允许哪些服务进行通信。可以使用可以实时更改的意图轻松管理服务分段,而不是使用复杂的网络拓扑和静态防火墙规则。
- 多数据中心:Consul 支持多个数据中心。这意味着 Consul 的用户不必担心构建额外的抽象层以扩展到多个区域。
Consul 是一个分布式,高度可用的系统。本节将介绍基础知识,故意省略一些不必要的细节,以便您快速了解Consul的工作原理。有关更多详细信息,请参阅 深入的体系结构概述
1、安装
- 通过官网地址下载对应的安装包
- 以 Linux 的为例,将安装包解压在任意喜欢的目录之中如: /usr/local
在 /usr/local 建立 consul 目录
将下载好的压缩包移动值该目录解压: unzip consul_1.4.4_linux_amd64.zip
为了方便起见,将得到的 consul 命令文件拷贝一份到 /usr/local/bin 目录之中即可全局使用
cp ./consul /usr/local/bin/
如若无误在任意位置输入: consul version 即可看到对应的 consul 的版本信息
Consul v1.4.4
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
2、启动
- 基本命令(前台启动)
consul agent -server -bind=192.168.xxx.134 -client=0.0.0.0 -bootstrap-expect=1 -data-dir=/usr/data/consul_data -node=server1
**-server ** 表示以服务端身份启动
**-bind ** 强制绑定到指定 IP
-client 指定客户端访问的 IP (consul 有丰富的 api 接口,这里的客户端指浏览器或调用方),0.0.0.0 表示不限制客户端 IP
-bootstrap-expect=3 表示 server 集群最低节点为 3,低于这个值将工作不正常(注:类似zookeeper一样,通常集群数为奇数,方便选举,consul采用的是raft算法)
-data-dir 表示指定数据的存放目录(该目录必须已存在)
-node 表示节点在 web ui 中显示的名称
启动成功后,不要关闭终端窗口,在浏览器之中访问:http://192.168.xxx.134:8500/ ,如若无误将会得到:
Consul Agent
- 后台启动
nohup consul agent -server -bind=192.168.xxx.134 -client=0.0.0.0 -bootstrap-expect=1 -data-dir=/usr/data/consul_data -node=server1 > /dev/null 2>&1 &
3、启动 client 端
- 与 Server 端类似,去除掉 -server 即可
nohup consul agent -bind=192.168.xxx.134 -http-port=8500 -dns-port=8600 -client=0.0.0.0 -data-dir=/usr/data/consul_data/ -node=client1 > /dev/null 2>&1 &
- 指定 http 与 dns 端口号
nohup consul agent -bind=192.168.xxx.134 -http-port=7500 -dns-port=7600 -client=0.0.0.0 -data-dir=/usr/data/consul_data/ -node=client1 > /dev/null 2>&1 &
4、带 UI 启动
nohup consul agent -server -bind=192.168.xxx.134 -client=0.0.0.0 -bootstrap-expect=1 -data-dir=/usr/data/consul_data -node=server1 -ui > /dev/null 2>&1 &
5、搭建集群
搭建多个节点,在多个节点中启动 Consul ,通过 join 命令关联示例
例如: 将当前节点添加到 192.168.xxx.131 节点之中
consul join 192.168.xxx.131
成功后,会输出:Successfully joined cluster by contacting 1 node
查看集群:consul members
Node Address Status Type Build Protocol DC Segment
server1 192.168.xxx.134:8301 alive server 1.4.4 2 dc1 <all>
server2 192.168.xxx.131:8301 alive server 1.4.4 2 dc1 <all>
6、服务注册/发现/注销
目前在 services 里,除了 consul 外,还没有其他服务,我们可以通过 service api 来进行注册,可以通过 postman、Insomnia 等 rest api工具或者 curl 命令,向 服务注册地址 进行注册,以 PUT 方式提交、Content-Type 为 application/json 格式,参数设置为以下 JSON 内容
{
"ID": "elasticsearchID",
"Service": "elasticsearch",
"Name":"my-service-name",
"Tags": [
"mytags=1"
],
"Meta": {
"elasticsearch_version": "4.0"
},
"Port": 8080,
"Address": "192.168.xxx.1",
"EnableTagOverride": false,
"Weights": {
"Passing": 10,
"Warning": 1
}
}
往 192.168.xxx.131 这台机器的注册一个名为 my-service-name,ID 为 elasticsearchID的服务
具体 API 解释与更多使用参考 官网
- 服务发现,查看已注册成功的服务
直接通过浏览器请求: http://192.168.xxx.131:8500/v1/agent/services 如若以上内容注册成功可获取到以下结果{ "elasticsearchID": { "ID": "elasticsearchID", "Service": "my-service-name", "Tags": [ "mytags=1" ], "Meta": { "elasticsearch_version": "4.0" }, "Port": 8080, "Address": "192.168.xxx.1", "Weights": { "Passing": 10, "Warning": 1 }, "EnableTagOverride": false } }
- 服务注销
通过 PUT 请求方式,调用: http://192.168.xxx.131:8500/v1/agent/service/deregister/elasticsearchID
即注销了elasticsearchID 这个服务信息,可调用 http://192.168.xxx.131:8500/v1/agent/services 查看该服务是否已被注销
7、开发者模式
前面的几步操作在开发的过程中操作起来的步骤相对繁琐,因此 consul 也为开发人员推出了开发者模式(即 dev) 使用方式及其简单,输入如下命令即可:
consul agent -dev
开发模式,自带了 web ui,当然此种方式也默认 IP 为: 127.0.0.1 ,所以直接输入:http://127.0.0.1:8500 访问 UI 页面
8、在 Spring Cloud 中使用 Consul
创建一个 Spring Cloud 工程「microcloud」,在该工程中使用 Consul
- 创建「microcloud」,配置父 pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.microcloud</groupId> <artifactId>microcloud</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>microcloud-consul-8501</module> </modules>
<name>microcloud</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url><properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<jdk.version>1.8</jdk.version>
</properties><dependencyManagement>
<dependencies>
<!--cloud父pom引用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--支持cloud-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement><build>
<finalName>microcloud</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source> <!--源码的JDK版本-->
<target>${jdk.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
<span ><!--资源文件打包管理--></span>
<span ><span ><span ><</span>resources</span><span >></span></span>
<span ><span ><span ><</span>resource</span><span >></span></span>
<span ><span ><span ><</span>directory</span><span >></span></span>src/main/resources<span ><span ><span ></</span>directory</span><span >></span></span>
<span ><span ><span ><</span>includes</span><span >></span></span>
<span ><span ><span ><</span>include</span><span >></span></span>**/*.properties<span ><span ><span ></</span>include</span><span >></span></span>
<span ><span ><span ><</span>include</span><span >></span></span>**/*.yml<span ><span ><span ></</span>include</span><span >></span></span>
<span ><span ><span ><</span>include</span><span >></span></span>**/*.xml<span ><span ><span ></</span>include</span><span >></span></span>
<span ><span ><span ><</span>include</span><span >></span></span>**/*.tld<span ><span ><span ></</span>include</span><span >></span></span>
<span ><span ><span ></</span>includes</span><span >></span></span>
<span ><span ><span ><</span>filtering</span><span >></span></span>true<span ><span ><span ></</span>filtering</span><span >></span></span>
<span ><span ><span ></</span>resource</span><span >></span></span>
<span ><span ><span ><</span>resource</span><span >></span></span>
<span ><span ><span ><</span>directory</span><span >></span></span>src/main/java<span ><span ><span ></</span>directory</span><span >></span></span>
<span ><span ><span ><</span>includes</span><span >></span></span>
<span ><span ><span ><</span>include</span><span >></span></span>**/*.properties<span ><span ><span ></</span>include</span><span >></span></span>
<span ><span ><span ><</span>include</span><span >></span></span>**/*.yml<span ><span ><span ></</span>include</span><span >></span></span>
<span ><span ><span ><</span>include</span><span >></span></span>**/*.xml<span ><span ><span ></</span>include</span><span >></span></span>
<span ><span ><span ><</span>include</span><span >></span></span>**/*.tld<span ><span ><span ></</span>include</span><span >></span></span>
<span ><span ><span ></</span>includes</span><span >></span></span>
<span ><span ><span ><</span>filtering</span><span >></span></span>true<span ><span ><span ></</span>filtering</span><span >></span></span>
<span ><span ><span ></</span>resource</span><span >></span></span>
<span ><span ><span ></</span>resources</span><span >></span></span>
</build>
</project>- 创建「microcloud-consul-8501」模块,配置 pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>microcloud</artifactId> <groupId>com.microcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microcloud-consul-8501</artifactId> <name>microcloud-consul-8501</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency>
<span ><span ><span ><</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.boot<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-boot-starter-web<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ><</span>exclusions</span><span >></span></span>
<span ><span ><span ><</span>exclusion</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.boot<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-boot-starter-tomcat<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ></</span>exclusion</span><span >></span></span>
<span ><span ><span ></</span>exclusions</span><span >></span></span>
<span ><span ><span ></</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.boot<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-boot-starter-test<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ></</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>junit<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>junit<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ><</span>scope</span><span >></span></span>test<span ><span ><span ></</span>scope</span><span >></span></span>
<span ><span ><span ></</span>dependency</span><span >></span></span>
<span ><!--consul 引用--></span>
<span ><span ><span ><</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.cloud<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-cloud-starter-consul-discovery<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ></</span>dependency</span><span >></span></span>
<span ><span ><span ></</span>dependencies</span><span >></span></span>
</project>
- 【microcloud-consul-8501】在 /src/main/resources 下创建配置文件 application.yml 配置文件,增加 Consul 配置
server: port: 8501 spring: cloud: consul: host: 127.0.0.1 port: 8500 discovery: tags: version=1.0,author=code health-check-path: /info # 为健康检查的url,由consul定时调用一次判断服务是否可用 health-check-interval: 5s # 检查间隔时间 instance-id: ${spring.application.name}:prod # 注册的服务ID service-name: ${spring.application.name} # 注册的服务名称 prefer-ip-address: true # 是否使用指定IP地址,默认为 false ip-address: 127.0.0.1 # 指定 IP 地址
application:
name: microcloud-consul-8501 - 【microcloud-consul-8501】配置检查健康服务类
package com.microcloud.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @Auther: xxx */ @RestController public class ConsulController {
<span ></span><span >(</span>value <span >=</span> <span >"/echo"</span><span >)</span>
<span >public</span> <span >String</span> <span >echo</span><span >(</span><span >String</span> message<span >)</span> <span >{</span>
<span >return</span> <span >"Echo:"</span> <span >+</span> message<span >;</span>
<span >}</span>
<span >/**
* consul 检查服务方法
* @return
*/</span>
<span ></span><span >(</span>value <span >=</span> <span >"/info"</span><span >)</span>
<span >public</span> <span >String</span> <span >info</span><span >(</span><span >)</span> <span >{</span>
<span >return</span> <span >"info"</span><span >;</span>
<span >}</span>
}
- 【microcloud-consul-8501】 启动类
package com.microcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
- @Auther: xxx
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
启动,测试
启动后可得到类似如下内容,即表示注册成功,可通过 Consul UI 地址查看到对应在服务信息
Registering service with consul: NewService{id='microcloud-consul-8501-prod', name='microcloud-consul-8501', tags=[version=1.0, author=code, secure=false], address='127.0.0.1', meta=null, port=8501, enableTagOverride=null, check=Check{script='null', interval='5s', ttl='null', http='http://127.0.0.1:8501/info', method='null', header={}, tcp='null', timeout='null', deregisterCriticalServiceAfter='null', tlsSkipVerify=null, status='null'}, checks=null}
访问: http://localhost:8500/v1/agent/services 将获取如下内容
{
"microcloud-consul-8501-prod": {
"ID": "microcloud-consul-8501-prod",
"Service": "microcloud-consul-8501",
"Tags": [
"version=1.0",
"author=code",
"secure=false"
],
"Meta": {},
"Port": 8501,
"Address": "127.0.0.1",
"Weights": {
"Passing": 1,
"Warning": 1
},
"EnableTagOverride": false
}
}
【microcloud-customer-80】通过 RestTemplate 调用在 Consul 中注册的服务,创建并配置 「microcloud-customer-80」 模块
配置 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>microcloud</artifactId>
<groupId>com.microcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>microcloud-customer-80</artifactId>
<span ><span ><span ><</span>name</span><span >></span></span>microcloud-customer-80<span ><span ><span ></</span>name</span><span >></span></span>
<span ><!-- FIXME change it to the project's website --></span>
<span ><span ><span ><</span>url</span><span >></span></span>http://www.example.com<span ><span ><span ></</span>url</span><span >></span></span>
<span ><span ><span ><</span>dependencies</span><span >></span></span>
<span ><span ><span ><</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.boot<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-boot-starter-jetty<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ></</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.boot<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-boot-starter-web<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ><</span>exclusions</span><span >></span></span>
<span ><span ><span ><</span>exclusion</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.boot<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-boot-starter-tomcat<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ></</span>exclusion</span><span >></span></span>
<span ><span ><span ></</span>exclusions</span><span >></span></span>
<span ><span ><span ></</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.boot<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-boot-starter-test<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ></</span>dependency</span><span >></span></span>
<span ><!--consul 引用--></span>
<span ><span ><span ><</span>dependency</span><span >></span></span>
<span ><span ><span ><</span>groupId</span><span >></span></span>org.springframework.cloud<span ><span ><span ></</span>groupId</span><span >></span></span>
<span ><span ><span ><</span>artifactId</span><span >></span></span>spring-cloud-starter-consul-discovery<span ><span ><span ></</span>artifactId</span><span >></span></span>
<span ><span ><span ></</span>dependency</span><span >></span></span>
<span ><span ><span ></</span>dependencies</span><span >></span></span>
</project>
创建 Rest 配置模板 Bean
package com.microcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* Rest 模板配置
* @Auther: xxx
*/
public class RestConfig {
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
Rest控制服务
package com.microcloud.controller;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.net.URI;
import java.util.List;
/**
@Auther: xxx
*/
@RestController
@RequestMapping(value = "/customer")
public class CustomerController {
@Resource
private RestTemplate restTemplate;
@Resource
private DiscoveryClient discoveryClient;
@GetMapping(value = "/info")
public String getInfo(String echo) {
String serviceName = "microcloud-consul-8501";
List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);
if (!CollectionUtils.isEmpty(instances)) {
URI uri = instances.get(0).getUri();
String result = restTemplate.getForObject(uri + "/echo?message=" + echo, String.class);
return result;
}
return "";
}
}
YAMl配置文件
server
port80
spring
application
name customer
cloud
consul
host127.0.0.1
port8500
服务启动
package com.microcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
@Auther: xxx
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
在浏览器中输入 http://localhost/customer/info?echo=Hello Consul 观察返回结果
如若无误会得到