1. consul简介
consul是常用的服务发现框架之一,consul是分布式的、高可用、横向扩展的。consul提供的一些关键特性:
- service discovery:consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易,一些外部服务,例如saas提供的也可以一样注册。
- health checking:健康检测使consul可以快速的告警在集群中的操作。和服务发现的集成,可以防止服务转发到故障的服务上面。
- key/value storage:一个用来存储动态配置的系统。提供简单的HTTP接口,可以在任何地方操作。
- multi-datacenter:无需复杂的配置,即可支持任意数量的区域。
2. consul的几个概念
上图来自于consul官方文档
我们只看数据中心1,可以看出consul的集群是由N个SERVER(服务端),加上N个CLIENT(客户端)组成的。而不管是SERVER还是CLIENT,都是consul的一个节点,所有的服务都可以注册到这些节点上,正是通过这些节点实现服务注册信息的共享。
除了这两个,还有一些小细节,一一简单介绍:
CLIENT
CLIENT表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到SERVER,本身是不持久化这些信息。
SERVER
SERVER表示consul的server模式,表明这个consul是个server,这种模式下,功能和CLIENT都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。
SERVER-LEADER
中间那个SERVER下面有LEADER的字眼,表明这个SERVER是它们的老大,它和其它SERVER不一样的一点是,它需要负责同步注册的信息给其它的SERVER,同时也要负责各个节点的健康监测。
其它信息其它信息包括它们之间的通信方式,还有一些协议信息,算法。它们是用于保证节点之间的数据同步,实时性要求等等一系列集群问题的解决。这些有兴趣的自己看看官方文档。
3. 安装consul
Consul 下载地址:https://www.consul.io/downloads.html,下载后解压就是一个可执行的二进制文件consul,检查 consul 是否可用:
如果出现上面这样代表consul是没问题的。
4. 运行consul
Consul安装之后,代理必须运行。 代理可以在服务器或客户端模式下运行。 每个数据中心都必须至少有一台服务器,但推荐使用3台或5台服务器。 一个单一的服务器部署是非常不推荐的,因为在故障情况下数据丢失是不可避免的。
所有其他代理以客户端模式运行。 客户端是一个非常轻量级的进程,它注册服务,运行健康检查,并将查询转发给服务器。 代理程序必须在集群中的每个节点上运行。
为了简单起见,我们现在将以开发模式启动Consul代理。 这种模式对于快速简单地启动单节点Consul环境非常有用。 它并不打算在生产中使用,因为它不会持续任何状态。
如您所见,Consul代理已经启动并输出了一些日志数据。 从日志数据中,您可以看到我们的代理正在服务器模式下运行,并声称拥有集群领导权。 此外,当地成员已被标记为该集群的健康成员。
测试访问consul控制台:http://localhost:8500/ui/dc1/services
注册“服务提供者”
- 引用consul的依赖
<!--consul-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
- 在yaml中进行配置
server:
port: 8006
spring:
application:
name: consul-provider-payment
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name} #指定服务名称
- 成功后可以在控制台查看到该服务节点的信息
注册“服务使用者”
- 创建消费服务对象:cloud-conslu-consumer-order80
- 在pom文件中添加consul的依赖引用
<dependencies>
<!--consul-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!--springboot-web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--自定义基础jar包-->
<dependency>
<groupId>com.atguigu.springboot</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--工具包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 在yaml文件中配置consul服务
server:
port: 80
spring:
application:
name: consul-consumer-order
devtools:
restart:
enabled: true
cloud:
consul:
discovery:
service-name: ${spring.application.name}
port: 8500
host: localhost
- 使用RestTemplater进行请求转发
@RestController
@Slf4j
public class OrderConsulController {
//声明请求路径
public static final String INVOKE_URL_ = "http://consul-provider-payment";
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/consul")
public String paymentInfo(){
String result = restTemplate.getForObject(INVOKE_URL_ + "/payment/consul",String.class);
return result ;
}
}
- 测试“服务使用者”是否可以请求到“服务提供者的”接口
consul客户端: