文章目录
SpringCloud从入门到放弃 03 ——Consul服务注册与发现
一、Consul简介
1.什么是consul
Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。
提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案。
它具有很多优点。包括: 基于 raft 协议,比较简洁; 支持健康检查, 同时支持 HTTP 和 DNS 协议 支持跨数据中心的 WAN 集群 提供图形界面 跨平台,支持 Linux、Mac、Windows
2.consul能做什么
二、安装并运行Consul
1.下载安装
consul 支持MacOS 、Linux、 windows 、FreeBSD 等操作系统,在官网上可以下载对应操作系统的版本,下载地址
如果要下载其他版本
consul windows 下是无需安装的,下载完成后直接解压可以得到一个直接能运行 consul执行文件:
查看版本信息:
2.启动consul
- 使用开发模式直接启动
执行命令:consul agent -dev
启动后访问:http://localhost:8500 可以看到整个consul的所有信息
三、创建服务消费者和服务提供者
创建服务提供者
1.新建module consul-provider-payment8006
2.修改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>cloudlearn</artifactId>
<groupId>com.avgrado.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consul-provider-payment8006</artifactId>
<dependencies>
<dependency>
<groupId>com.avgrado.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</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-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>
</project>
3.写application.yml文件
server:
port: 8006
spring:
application:
name: consul-provider-payment
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
4.写启动类(此处启动类上面的注解是@EnableDiscoveryClient)
package com.avgrado.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @ClassName PaymentConsulApplication
* @Description PaymentConsulApplication8006
* @Author avgrado
*/
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentConsulApplication8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentConsulApplication8006.class,args);
}
}
5.写业务类
package com.avgrado.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
/**
* @ClassName PaymentConsulController8006
* @Description PaymentConsulController8006
* @Author avgrado
*/
@RestController
@Slf4j
public class PaymentConsulController8006 {
@Value("${server.port}")
private String serverPort;
@GetMapping("/consul/getPayment")
public String getPayment(){
String result = "springcloud with consul "+serverPort + "=="+ UUID.randomUUID().toString();
log.info(result);
return result;
}
}
6.验证测试
创建服务消费
1.新建 module consul-consumer-order80
2.修改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>cloudlearn</artifactId>
<groupId>com.avgrado.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consul-consumer-order80</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.avgrado.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</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>
</project>
3.写 yml 文件
server:
port: 80
spring:
application:
name: consul-consumer-order
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
4.写主启动类
package com.avgrado.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @ClassName OrderConsulApplication80
* @Description OrderConsulApplication80
* @Author avgrado
*/
@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulApplication80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulApplication80.class,args);
}
}
5.配置 bean
package com.avgrado.springcloud.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;
/**
* @ClassName RestConfig
* @Description RestConfig
* @Author avgrado
*/
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
6.写业务类
package com.avgrado.springcloud.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
/**
* @ClassName OrderConsulController
* @Description OrderConsulController
* @Author avgrado
*/
@RestController
public class OrderConsulController {
public static final String INVOKE_URL = "http://consul-provider-payment";
@Resource
RestTemplate restTemplate;
@GetMapping("/consumer/get")
public String consulGetPayment(){
return restTemplate.getForObject(INVOKE_URL+"/consul/getPayment",String.class);
}
}
7.验证测试
8.访问地址 http://localhost/consumer/get
四、和Eureka、zookeeper作为注册中心的异同点
和Eureka相比较
Consul:强一致性(CP):
-
服务注册相比Eureka会稍慢一些。因为Consul的Raft协议要求必须过半的节点都写入成功才认为注册成功。
-
Leader挂掉后,重新选举期间整个Consul不可用。保证了强一致性,但牺牲了可用性。
Eureka:高可用性和最终一致性(AP):
-
服务注册相对要快,因为不需要等注册信息复制到其他节点,也不保证注册信息是否复制成功。
-
当数据出现不一致的时候,虽然A,B上的注册信息不完全相同,但是每个Eureka节点依然能够正常对外提供服务,这会出现查询服务信息时如果请求A查不到,但请求B就能查到。如果保证了可用性但牺牲了一致性。
和zookeeper相比较
-
ZooKeeper的主要功能:
(1)作为配置信息的存储的中心服务器
(2)命名服务
(3)分布式同步
(4)分组服务
如果只是打算将ZooKeeper作为微服务发现工具,就需要用到其配置存储和分布式同步的功能。前者可以理解成具有一致性的KV存储,后者提供了ZooKeeper特有的watcher注册于异步通知机制,ZooKeeper能将节点的状态实时异步通知给ZooKeeper客户端。
ZooKeeper提供临时节点,这些节点是客户端断开连接时删除的K / V条目。这些比心跳系统更复杂,但仍然存在固有的可扩展性问题并增加了客户端的复杂性。所有客户端必须保持与ZooKeeper服务器的活动连接并执行保持活动。另外,这需要“厚客户端”,这些客户端难以编写并且经常导致调试挑战 -
2.Consul的主要功能 :
(1) 通过DNS或HTTP,服务发现功能简单
(2)多种健康的检查方式:http返回码200,内存是否超限,tcp连接是否成功
(3) KV存储
(4)多数据中心(这个zookeeper没有)
Consul为服务发现、健康检测、K/V存储和多数据中心提供了一流的支持。为了支持任意存储,而不仅仅是简单的K/V存储,其他系统都要求工具和lib库要率先建立。然而,通过使用客户端节点,Consul提供了一个简单的API,这个API的开发只需要瘦客户端就可以了, 而且,通过使用配置文件和DNS接口,开发人员可以建立完整的服务发现解决方案,最终,达到避免开发API的目的