本篇博客参考学习视频
一、Eureka 服务注册与发现
① Eureka 基础知识
1. 服务治理
SpringCloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理。 在传统的 RPC 远程调用框架中, 管理每个服务与服务之间依赖关系比较复杂, 所以需要使用服务治理管理服务与服务之间依赖关系, 了以实现服务调用、 负载均衡、容错等, 实现服务发现与注册 。
2. 服务注册


3.Eureka 两组件

② 单机 Eureka 构建步骤
1.IDEA 生成 EurekaServer 端服务注册中心 类似物业公司
建 Module

代码语言:javascript复制改 POM
<dependencies>
<!--eureka-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-common</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>1.X 和 2.X 的对比说明

代码语言:javascript复制写 YML
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/代码语言:javascript复制主启动
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class, args);
}
}注意:需要在启动类上配置注解 @EnableEurekaServer,开启注册中心
测试
http://localhost:7001/ ,效果页面

2.EurekaClient 端 cloud-provider-payment8001 将注册进 EurekaServer 成为服务提供者 provider
代码语言:javascript复制改 POM ( cloud-provider-payment8001)
<!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>1.X 和 2.X 的对比说明

代码语言:javascript复制写 YML
eureka:
client:
# 表示是否将自己注册进eurekaServer 默认为 true。
register-with-eureka: true
# 是否从EureaServer 抓取已有的注册信息,默认为true.单节点无所谓,集群必须设置true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka代码语言:javascript复制主启动
@EnableEurekaClient
@SpringBootApplication
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args);
}
}添加:注解 @EnableEurekaClient
测试
- 先启动 EurekaServer http://localhost:7001/

- 微服务配置说明

- 自我保护机制

3.EurekaClient 端 cloud-consumer-order80 将注册进 EurekaServer 成为服务消费者 consumer
代码语言:javascript复制改 POM
<!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>代码语言:javascript复制写 YML
spring:
application:
name: cloud-order-service
eureka:
client:
register-with-eureka: true
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka代码语言:javascript复制主启动 @EnableEurekaClient
@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class, args);
}
}测试
- 先启动 EurekaServer, 7001 服务,在启动服务提供者 provider 8001 服务,在启动消费者 consumer 80

- http://localhost/consumer/payment/get/1

BUG

③ Eureka 构建步骤
1.Eureka 集群原理说明

**微服务 RPC 远程服务调用最核心的是什么 **
代码语言:javascript复制高可用解决办法:搭建 Eureka 注册中心集群,实现负载均衡 故障容错
2.EurekaServer 集群环境构建步骤
新建 cloud-eureka-server7002 和 POM
参考 cloud-eureka-server7001 项目工程
修改映射配置
找到 C:WindowsSystem32driversetc 路径下的 hosts 文件

修改映射配置添加进 hosts 文件
- 127.0.0.1 eureka7001.com
- 127.0.0.1 eureka7002.com

写 YML
- 以前单机

- 7001
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7002.com:7002/eureka/ #设置与 eureka server 交互的地址查询服务和注册服务都需要依赖这个地址- 7002
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/ #设置与 eureka server 交互的地址查询服务和注册服务都需要依赖这个地址代码语言:javascript复制主启动类 (参考 cloud-eureka-server7001 的主启动类 )
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7002 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7002.class, args);
}
}3.将支付服务 8001 微服务发布到上面 2 台 Eureka 集群配置中
代码语言:javascript复制YML
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
4.将订单服务 80 微服务发布到上面 2 台 Eureka 集群配置中
代码语言:javascript复制YML
eureka:
client:
register-with-eureka: true
fetchRegistry: true
service-url:
# defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
5.测试 01
- 先要启动 EurekaServer, 7001/7002 服务,再要启动服务提供者 provider, 8001 服务,再要启动消费者, 80

- http://localhost/consumer/payment/get/1

6.支付服务提供者 8001 集群环境构建
新建 cloud-provider-payment8002 和 POM
参考 cloud-provider-payment8001
代码语言:javascript复制写 YML
server:
port: 8002
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: 6090
mybatis:
mapperLocations: classpath:mapper/*.xml
type-aliases-package: com.oy.springcloud.entities # 所有Entity别名类所在包
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
# 集群版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka代码语言:javascript复制主启动
@EnableEurekaClient
@SpringBootApplication
public class PaymentMain8002 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8002.class, args);
}
}业务类 直接从 8001 粘贴

代码语言:javascript复制修改 8001/8002 的 controller
@Value("${server.port}")
private String serverPort;- 8001 和 8002

7.负载均衡
Bug: 订单服务访问地址不能写死
原本:(cloud-consumer-order80)

更改:
代码语言:javascript复制public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";使用@LoadBalanced 注解赋予 RestTemplate 负载均衡的能力 (cloud-consumer-order80)

8.测试 02
- 先要启动 EurekaServer, 7001/7002 服务
- 再要启动服务提供者 provider, 8001/8002 服务
- 在启动 consumer 80 服务
- http://localhost/consumer/payment/get/1 **负载均衡生效, 8001/8002 端口交替出现 **

④ actuator 微服务信息完善
1.主机名称:服务名称修改
代码语言:javascript复制修改 YML (cloud-provider-payment8001) 部分
instance:
instance-id: payment8001
2.访问信息有 ip 信息提示
当前问题:没有 ip 提示
代码语言:javascript复制修改 cloud-provider-payment8001 YML 部分
prefer-ip-address: true
_效果_:

⑤ 服务发现 Discovery
1.对于注册进 eureka 里面的微服务,可以通过服务发现来获取服务的信息
2.修改 cloud-provider-payment8001 的 Controller
代码语言:javascript复制@Resource
private DiscoveryClient discoveryClient;
@GetMapping(value = "/payment/discovery")
public Object discovery(){
List<String> services = discoveryClient.getServices();
for (String element : services) {
log.info("**** element:" element);
}
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance : instances) {
log.info(instance.getServiceId() "t" instance.getHost() "t" instance.getPort() "t" instance.getUri());
}
return this.discoveryClient;
}3.8001 主启动类
代码语言:javascript复制@EnableDiscoveryClient
@EnableEurekaClient
@EnableDiscoveryClient // 服务发现
@SpringBootApplication
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args);
}
}4.测试
- 先启动 EurekaServer, 7001/7002 服务,再启动 8001 主启动类,需要稍等一会 http://localhost:8001/payment/discovery

⑥ Eureka 自我保护
1.故障现象

2.导致原因


总结:某时刻某一个微服务不可用了,Eureka 不会立即清理,依旧会对该服务的信息进行保存,属于 CAP 里的 AP 分支
3.怎么禁止自我保护(一般生产环境中不会禁止自我保护)
注册中心 eureakeServer 端 7001: 出 厂 默 认 , 自 我 保 护 机 制 是 开 启的:eureka.server.enable-self-preservation = true
- 使用 eureka.server.enable-self-preservation = false 可以禁用自我保护模式
- 在 eurekaServer 端 7001 处设置关闭自我保护机制

效果图:

生产者客户端 eureakeClient 端 8001
默认:
代码语言:javascript复制eureka.instance.lease-renewal-interval-in-seconds=30 单位为秒( 默认是 30 秒)
eureka.instance.lease-expiration-duration-in-seconds=90 单 位 为 秒( 默认是 90 秒)配置:

instance:
instance-id: payment8001
prefer-ip-address: true
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 24.测试
- 7001 和 8001 都配置完成
- 先启动 7001 再启动 8001 ,先关闭 8001 ,马上被删除了

二、Zookeeper 服务注册与发现
① Eukeka 停止更新了怎么办
https://github.com/Netflix/eureka/wiki
② SpringCloud 整合 Zookeeper 代替 Eureka
1.注册中心 zookeeper
- zookeeper 是一个分布式协调工具,可以实现注册中心功能
使用 docker 快速创建 zookeeper 容器
- 关闭 Linux 服务器防火墙后启动 zookeeper 服务器
CentOS 7 关闭防火墙指令
代码语言:javascript复制// 查看当前防火墙状态如果防火墙处于开启状态,firewalld.service前面的点是高亮的,Active:active(开启))
systemctl status firewalld.service
//关闭当前的防火墙(仅对本次开机有效,重启后防火墙会再次启用)
systemctl stop firewalld.service
//永久关闭防火墙(重启后防火墙依然关闭)
systemctl disable firewalld.service
// 启动防火墙
systemctl start firewalld- zookeeper 服务器取代 Eureka 服务器,zk 作为服务器注册中心
2.服务提供者
代码语言:javascript复制新建 cloud-provider-payment8004
POM
<?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>clould</artifactId>
<groupId>com.oy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-provider-payment8004</artifactId>
<description>Zookeeper服务提供者</description>
<dependencies>
<dependency>
<groupId>com.oy</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringBoot整合Zookeeper客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</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>代码语言:javascript复制YML
server:
# 8004表示注册到zookeeper服务器的支付服务提供者端口号
port: 8004
spring:
application:
# 服务别名---注册zookeeper到注册中心的名称
name: cloud-provider-payment
cloud:
zookeeper:
connect-string: 116.63.177.72:2181代码语言:javascript复制主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain8004 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8004.class, args);
}
}代码语言:javascript复制Controller
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/zk")
public String paymentzk(){
return "springcloud with zookeeper:" serverPort "t" UUID.randomUUID().toString();
}
}启动 8004 注册进 zookeeper

注意:启动后问题存在下面问题

Why:
- 解决 zookeeper 版本 jar 包冲突问题:

- 排出 zk 冲突后的新 POM:
<?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>cloud2020</artifactId>
<groupId>com.atguigu.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-provider-payment8004</artifactId>
<description>Zookeeper服务提供者</description>
<dependencies>
<!--SpringBoot整合Zookeeper客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<exclusions>
<!--先排除自带的zookeeper3.5.3-->
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加zookeeper3.4.9版本-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</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>测试
- 在 Linux 上查询 和 浏览器上(http://localhost:8004/payment/zk )

- 获得 json 串后用在线工具查看试试 (dokcer 容器) 具体详细的操作参考:https://blog.csdn.net/qq_45738810/article/details/109002435


思考: 服务节点是临时节点还是持久节点——是临时节点
3.服务消费者
代码语言:javascript复制新建 cloud-consumerzk-order80
POM
<?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>cloud2020</artifactId>
<groupId>com.atguigu.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumerzk-order80</artifactId>
<dependencies>
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringBoot整合Zookeeper客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<exclusions>
<!--先排除自带的zookeeper3.5.3-->
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加zookeeper3.4.9版本-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</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>代码语言:javascript复制YML
server:
port: 80
spring:
application:
# 服务别名
name: cloud-consumer-order
cloud:
zookeeper:
# 注册到zookeeper地址
connect-string: localhost:2181代码语言:javascript复制主启动
@SpringBootApplication
@EnableDiscoveryClient
public class OrderZkMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderZkMain80.class, args);
}
}主业务类
- bean
package com.springcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @Author OY
* @Date 2020/10/10
*/
@Configuration
public class ApplicationContextConfig {
@Bean
public RestTemplate restTemplate(){
return restTemplate();
}
}- controller
package com.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
/**
* @Author OY
* @Date 2020/10/10
*/
@RestController
@Slf4j
public class OrderZkController {
@Resource
private RestTemplate restTemplate;
public static final String INVOKE_URL = "http://cloud-provider-payment";
@GetMapping("/consumer/payment/zk")
public String paymentInfo() {
return restTemplate.getForObject(INVOKE_URL "/payment/zk", String.class);
}
}验证测试

访问测试地址
http://localhost/consumer/payment/zk

三、Consul 服务注册与发现
① Consul 简介
1.是什么:https://www.consul.io/intro/index.html


2.能干嘛:
- 服务发现: 提供 HTTP 和 DNS 两种发现方式
- 健康检查: 支持多种协议,HTTP、TCP、Docker、Shell 脚本定制化
- KV 存储: Key,Value 的存储方式
- 多数据中心: Consul 支持多数据中心
- 可视化 Web 界面
3.下载
https://www.consul.io/downloads.html
4.怎么玩
https://www.springcloud.cc/spring-cloud-consul.html
② 安装并运行 Consul
1.官网安装说明
https://learn.hashicorp.com/consul/getting-started/install.html
2.下载完成后只有一个 consul.exe 文件,硬盘路径下双击运行,查看版本信息

3.使用开发者模式启动
代码语言:javascript复制consul agent -dev
通过以下地址可以访问 Consul 的首页:http://localhost:8500/

③ 服务提供者
新 建 Module 支 付 服 务 provider8006
cloud-providerconsul-payment8006
代码语言:javascript复制POM
<?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>clould</artifactId>
<groupId>com.oy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-providerconsul-payment8006</artifactId>
<dependencies>
<!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-consul-discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.oy</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>代码语言:javascript复制YML
server:
port: 8006
spring:
application:
name: consul-provider-payment
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}代码语言:javascript复制主启动类
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class, args);
}
}代码语言:javascript复制主业务类 Controller
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/consul")
public String paymentConsul(){
return "SpringCloud with consul:" serverPort "t" UUID.randomUUID().toString();
}
}验证测试
http://localhost:8006/payment/consul

④ 服务消费者
新 建 Module 消 费 服 务 order8006
cloud-consumerconsul-order80
代码语言:javascript复制POM
<?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>clould</artifactId>
<groupId>com.oy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumerconsul-order80</artifactId>
<dependencies>
<!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-consul-discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.oy</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope></dependency>
</dependencies>
</project>代码语言:javascript复制YML
server:
port: 80
spring:
application:
name: consul-consumer-order
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}代码语言:javascript复制主启动类
package com.oy.springcloud;
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);
}
}代码语言:javascript复制配置 Bean
package com.oy.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;
@Configuration
public class ApplicationConfig {
@LoadBalanced // 负载均衡
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}代码语言:javascript复制Controller
package com.oy.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
/**
* @Author OY
* @Date 2020/10/11
*/
@RestController
@Slf4j
public class OrderConsulController {
public static final String INVOME_URL = "http://consul-provider-payment";
@Resource
public RestTemplate restTemplate;
@GetMapping("/consumer/payment/consul")
public String payment(){
String result = restTemplate.getForObject(INVOME_URL "/payment/consul",String.class );
return result;
}
}验证测试

访问测试地址:http://localhost/consumer/payment/consul

⑤ 三个注册中心异同点
1.CAP
- C: Consistency (强一致性)
- A: Availability (可用性)
- P: Partition tolerance (分区容错)
CAP 理论关注粒度是数据, 而不是整体系统设计的策略
2.经典 CAP 图


AP(Eureka) 架构
当网络分区出现后,为了保证可用性,系统 B可以返回值,保证系统的可用性。
结论:违背了一致性 C 的要求,只满足可用性和分区容错,即 AP

CP(Zookeeper/Consul) 架构



