一、Consul是什么

Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul的方案更"一站式",内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。使用起来也较 为简单。Consul用Golang实现,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与Docker等轻量级容器可无缝配合。

Consul包含多个组件,提供以下特性:

  • 服务发现 Consul的客户端可用提供一个服务,比如 api 或者mysql ,另外一些客户端可用使用Consul去发现一个指定服务的提供者.通过DNS或者HTTP应用程序可用很容易的找到他所依赖的服务.
  • 健康检查 Consul客户端可用提供任意数量的健康检查,指定一个服务(比如:webserver是否返回了200 OK 状态码)或者使用本地节点(比如:内存使用是否大于90%). 这个信息可由operator用来监视集群的健康.被服务发现组件用来避免将流量发送到不健康的主机.
  • Key/Value存储 应用程序可用根据自己的需要使用Consul的层级的Key/Value存储.比如动态配置,功能标记,协调,领袖选举等等,简单的HTTP API让他更易于使用.
  • 多数据中心: Consul支持开箱即用的多数据中心.这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域.

详细内容请查看网站:https://www.consul.io/intro/index.html

二、Consul常用术语

  • Agent:Consul集群中长时间运行的守护进程,以consul agent 命令开始启动. 在客户端和服务端模式下都可以运行,可以运行DNS或者HTTP接口, 它的主要作用是运行时检查和保持服务同步。
  • Client: 客户端, 无状态, 以一个极小的消耗将接口请求转发给局域网内的服务端集群.
  • server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯. 每个数据中心的 server 数量推荐为 3 个或是 5 个.
  • Datacenter: 数据中心,多数据中心联合工作保证数据存储安全快捷
  • Consensus: 一致性协议使用的是Raft Protocol
  • RPC: 远程程序通信Architecture of Consul :

三、Consul安装

3.1.下载consul

下载地址:https://www.consul.io/downloads.html

Consul实现服务注册与发现_spring

3.2.如果使用consul

请点击 网址 即可获取consul在springcloud中的使用 是中文文档 https://www.springcloud.cc/spring-cloud-consul.html

Consul实现服务注册与发现_spring_02

3.3.查看consul版本信息

Windows版本 下载完成后只有一个consul.exe文件 路径下双击运行,查看版本信息

Consul实现服务注册与发现_数据中心_03

3.4.开发模式启动consul

通过如下命令启动:

consul agent -dev

启动后如下图:

Consul实现服务注册与发现_数据中心_04

3.5.测试 访问 consul

在浏览器输入 http://localhost:8500,如下图所示,表示成功。

Consul实现服务注册与发现_数据中心_05

四、创建服务提供者

4.1.创建模块 cloud-providerconsul-payment8006 作为服务提供者

如下图所示,就是一个基本的meavn模块

Consul实现服务注册与发现_客户端_06

设置模块的名字

Consul实现服务注册与发现_客户端_07

4.2.在pom中导入依赖

这里跟之前的区别就是需要导入consul的依赖

<dependencies>
<!--SpringCloud consul-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.augus.springcloud</groupId>
<artifactId>cloud-api-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<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>
<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>

4.2.创建application.yml配置文件

application.yml配置文件中主要是需要将payment注册到consul注册中心中

server:
# 服务器端口号
port: 8006

spring:
application:
# 服务名
name: consul-provider-payment
cloud:
consul:
# consul注册中心地址
host: localhost
port: 8500
discovery:
hostname: 127.0.0.1
service-name: ${spring.application.name}

4.3.创建主启动类

在com.augus.cloud 目录下创建主启动类 PaymentMain8006 

package com.augus.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient //指定为服务器提供者者客户端
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class, args);
}
}

4.4.创建业务类controller

在com.augus.cloud 目录下创建controller包,在下面创建PaymentController代码如下:

package com.augus.cloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
@Slf4j
public class PaymentController {

@Value("${server.port}")
private String serverPort;

@RequestMapping(value = "/payment/consul")
public String payment(){
return "SpringCloud with consul端口号:"+ serverPort+"\t"+ UUID.randomUUID().toString();
}
}

4.4.测试验证是否能将8006注册到consul注册中心

启动8006,然后访问 http://localhost:8500,即可看到

Consul实现服务注册与发现_客户端_08

 浏览器访问 http://localhost:8006/payment/consul 查看如下图:

Consul实现服务注册与发现_客户端_09

五、服务消费者

5.1.新建Module作为消费服务 cloud-consumerconsul-order80

创建maven模块

Consul实现服务注册与发现_客户端_10

设置模块名 cloud-consumerconsul-order80

Consul实现服务注册与发现_客户端_11

5.2.在pom中引入依赖

这里引入的服务提供者完全相同,使用的时候直接复制:

<dependencies>
<!--SpringCloud consul-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.augus.springcloud</groupId>
<artifactId>cloud-api-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<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>
<!--热部署-->
<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>

5.3.创建配置文件application.yml

在配置文件中主要设置将 消费者注册到consul服务注册中心

server:
# 服务器端口号
port: 80

spring:
application:
# 服务名
name: cloud-consumer-order
cloud:
consul:
# consul注册中心地址
host: localhost
port: 8500
discovery:
hostname: 127.0.0.1
service-name: ${spring.application.name}

5.4.创建主启动类

在com.augus.cloud包下创建 OrderConsulMain80.java 作为主启动类,代码如下:

package com.augus.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class,args);
}
}

5.5.配置bean

在在com.augus.cloud包 创建子包config,里面创建 ApplicationContextConfig.java,代码如下:

package com.augus.cloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //实现访问多个订单服务时候的负载均衡
public RestTemplate getTemplate(){
return new RestTemplate();
}
}

5.6.创建Controller中内容

package com.augus.cloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@Slf4j
public class OrderController {
//消费者服务地址
public static final String INVOKE_URL = "http://consul-provider-payment";

@Autowired
private RestTemplate restTemplate;

@GetMapping(value = "/consumer/payment/consul")
public String paymentInfo() {
return restTemplate.getForObject(INVOKE_URL + "/payment/consul", String.class);
}
}

5.7.验证测试

访问:http://localhost:8500/ 查看consul注册中心,如下图:

Consul实现服务注册与发现_spring_12

访问http://localhost/consumer/payment/consul 通过消费者调用服务提供者,如下图:

Consul实现服务注册与发现_数据中心_13

六、注册中心对比和选型:Zookeeper、Eureka和Consul

6.1.常见的注册中心比较

常见的注册中心有一下几个:

Consul实现服务注册与发现_客户端_14

6.2.1.CAP理论

CAP理论是分布式架构中重要理论, 它包含:
  • 一致性(Consistency):所有节点在同一时间具有相同的数据
  • 可用性(Availability) :保证每个请求不管成功或者失败都有响应(某个系统的某个节点挂了,但是并不影响系统的接受或者发出请求)
  • 分区容错性(Partition tolerance) 系统中任意信息的丢失或失败不会影响系统的继续运作 (在整个系统中某个部分,挂掉了,或者宕机了,并不影响整个系统的运作或者说使用)
  • AP :当网络分区出现后,为了保证可用性,系统B可以返回旧值,保证系统的可用性。结论:违背了一致性C的要求,只满足可用性和分区容错,即AP,代表性的就是eureka
  • CP:当网络分区出现后,为了保证一致性,就必须拒绝请求,否则无法保证一致性。结论:违背了可用性A的要求,只满足一致性和分区容错,即CP,代表性的是consul和zookeeper

Consul实现服务注册与发现_客户端_15

CAP不可能都满足,原因如下:

  • 如果C是第一需求的话,那么会影响A的性能。因为要数据同步,不然请求结果会有差异,但是数据同步会消耗时间,可用性就会降低。
  • 如果A是第一需求,那么只要有一个服务在,就能正常接受请求。但是对于返回结果便不能保证,原因是,在分布式部署的时候,数据一致的过程不可能像切线路那么快。
  • 如果同时满足一致性和可用性,那么分区容错就很难保证了。但是CAP理论提出就是针对分布式数据库环境的,所以P这个属性是必须具备的。P就是在分布式环境中,由于网络的问题可能导致某个节点和其它节点失去联系,这时候就形成了P(partition)。