本篇博客参考学习视频
一、Eureka 服务注册与发现
① Eureka 基础知识
1. 服务治理
SpringCloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理。 在传统的 RPC 远程调用框架中, 管理每个服务与服务之间依赖关系比较复杂, 所以需要使用服务治理管理服务与服务之间依赖关系, 了以实现服务调用、 负载均衡、容错等, 实现服务发现与注册 。
2. 服务注册
3.Eureka 两组件
② 单机 Eureka 构建步骤
1.IDEA 生成 EurekaServer 端服务注册中心 类似物业公司
建 Module
改 POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <dependencies> <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 的对比说明
写 YML
1 2 3 4 5 6 7 8 9 10 11
| server: port: 7001
eureka: instance: hostname: localhost client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
|
主启动
1 2 3 4 5 6 7
| @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
改 POM ( cloud-provider-payment8001)
1 2 3 4 5
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
|
1.X 和 2.X 的对比说明
写 YML
1 2 3 4 5 6 7 8
| eureka: client: register-with-eureka: true fetchRegistry: true service-url: defaultZone: http://localhost:7001/eureka
|
主启动
1 2 3 4 5 6 7
| @EnableEurekaClient @SpringBootApplication public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); } }
|
添加:注解 @EnableEurekaClient
测试
3.EurekaClient 端 cloud-consumer-order80 将注册进 EurekaServer 成为服务消费者 consumer
改 POM
1 2 3 4 5
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
|
写 YML
1 2 3 4 5 6 7 8 9
| spring: application: name: cloud-order-service eureka: client: register-with-eureka: true fetchRegistry: true service-url: defaultZone: http://localhost:7001/eureka
|
主启动 @EnableEurekaClient
1 2 3 4 5 6 7
| @SpringBootApplication @EnableEurekaClient public class OrderMain80 { public static void main(String[] args) { SpringApplication.run(OrderMain80.class, args); } }
|
测试
- 先启动 EurekaServer, 7001 服务,在启动服务提供者 provider 8001 服务,在启动消费者 consumer 80
BUG
③ Eureka 构建步骤
1.Eureka 集群原理说明
**微服务 RPC 远程服务调用最核心的是什么 **
解决办法:搭建 Eureka 注册中心集群,实现负载均衡+故障容错
2.EurekaServer 集群环境构建步骤
新建 cloud-eureka-server7002 和 POM
参考 cloud-eureka-server7001 项目工程
修改映射配置
找到 C:\Windows\System32\drivers\etc 路径下的 hosts 文件
修改映射配置添加进 hosts 文件
- 127.0.0.1 eureka7001.com
- 127.0.0.1 eureka7002.com
写 YML
1 2 3 4 5 6 7 8 9 10 11
| server: port: 7001
eureka: instance: hostname: eureka7001.com client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://eureka7002.com:7002/eureka/
|
1 2 3 4 5 6 7 8 9 10 11
| server: port: 7002
eureka: instance: hostname: eureka7002.com client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://eureka7001.com:7001/eureka/
|
主启动类 (参考 cloud-eureka-server7001 的主启动类 )
1 2 3 4 5 6 7
| @SpringBootApplication @EnableEurekaServer public class EurekaMain7002 { public static void main(String[] args) { SpringApplication.run(EurekaMain7002.class, args); } }
|
3.将支付服务 8001 微服务发布到上面 2 台 Eureka 集群配置中
YML
1 2 3 4 5 6
| 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 集群配置中
YML
1 2 3 4 5 6 7
| eureka: client: register-with-eureka: true fetchRegistry: true service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
|
5.测试 01
- 先要启动 EurekaServer, 7001/7002 服务,再要启动服务提供者 provider, 8001 服务,再要启动消费者, 80
6.支付服务提供者 8001 集群环境构建
新建 cloud-provider-payment8002 和 POM
参考 cloud-provider-payment8001
写 YML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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
eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
|
主启动
1 2 3 4 5 6 7
| @EnableEurekaClient @SpringBootApplication public class PaymentMain8002 { public static void main(String[] args) { SpringApplication.run(PaymentMain8002.class, args); } }
|
业务类 直接从 8001 粘贴
修改 8001/8002 的 controller
1 2
| @Value("${server.port}") private String serverPort;
|
7.负载均衡
Bug: 订单服务访问地址不能写死
原本:(cloud-consumer-order80)
更改:
1
| public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
|
使用@LoadBalanced 注解赋予 RestTemplate 负载均衡的能力 (cloud-consumer-order80)
8.测试 02
④ actuator 微服务信息完善
1.主机名称:服务名称修改
修改 YML (cloud-provider-payment8001) 部分
1 2
| instance: instance-id: payment8001
|
2.访问信息有 ip 信息提示
当前问题:没有 ip 提示
修改 cloud-provider-payment8001 YML 部分
_效果_:
⑤ 服务发现 Discovery
1.对于注册进 eureka 里面的微服务,可以通过服务发现来获取服务的信息
2.修改 cloud-provider-payment8001 的 Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @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 主启动类
@EnableDiscoveryClient
1 2 3 4 5 6 7 8
| @EnableEurekaClient @EnableDiscoveryClient @SpringBootApplication public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); } }
|
4.测试
⑥ Eureka 自我保护
1.故障现象
2.导致原因
总结
:某时刻某一个微服务不可用了,Eureka 不会立即清理,依旧会对该服务的信息进行保存,属于 CAP 里的 AP 分支
3.怎么禁止自我保护(一般生产环境中不会禁止自我保护)
注册中心 eureakeServer 端 7001: 出 厂 默 认 , 自 我 保 护 机 制 是 开 启的:eureka.server.enable-self-preservation = true
效果图:
生产者客户端 eureakeClient 端 8001
默认:
1 2
| eureka.instance.lease-renewal-interval-in-seconds=30 单位为秒( 默认是 30 秒) eureka.instance.lease-expiration-duration-in-seconds=90 单 位 为 秒( 默认是 90 秒)
|
配置:
1 2 3 4 5 6 7
| instance: instance-id: payment8001 prefer-ip-address: true lease-renewal-interval-in-seconds: 1 lease-expiration-duration-in-seconds: 2
|
4.测试
- 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 关闭防火墙指令
1 2 3 4 5 6 7 8 9 10 11
| // 查看当前防火墙状态如果防火墙处于开启状态,firewalld.service前面的点是高亮的,Active:active(开启)) systemctl status firewalld.service
//关闭当前的防火墙(仅对本次开机有效,重启后防火墙会再次启用) systemctl stop firewalld.service
//永久关闭防火墙(重启后防火墙依然关闭) systemctl disable firewalld.service
// 启动防火墙 systemctl start firewalld
|
- zookeeper 服务器取代 Eureka 服务器,zk 作为服务器注册中心
2.服务提供者
新建 cloud-provider-payment8004
POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| <?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> <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>
|
YML
1 2 3 4 5 6 7 8 9 10 11
| server:
port: 8004
spring: application:
name: cloud-provider-payment cloud: zookeeper: connect-string: 116.63.177.72:2181
|
主启动类
1 2 3 4 5 6 7 8 9 10 11 12
| 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); } }
|
Controller
1 2 3 4 5 6 7 8 9 10 11 12
| @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 包冲突问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| <?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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <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>
|
测试
思考: 服务节点是临时节点还是持久节点——是临时节点
3.服务消费者
新建 cloud-consumerzk-order80
POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| <?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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <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>
|
YML
1 2 3 4 5 6 7 8 9 10
| server: port: 80 spring: application: name: cloud-consumer-order cloud: zookeeper: connect-string: localhost:2181
|
主启动
1 2 3 4 5 6 7
| @SpringBootApplication @EnableDiscoveryClient public class OrderZkMain80 { public static void main(String[] args) { SpringApplication.run(OrderZkMain80.class, args); } }
|
主业务类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.springcloud.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate;
@Configuration public class ApplicationContextConfig {
@Bean public RestTemplate restTemplate(){ return restTemplate(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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;
@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 简介
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.使用开发者模式启动
通过以下地址可以访问 Consul 的首页:http://localhost:8500/
③ 服务提供者
新 建 Module 支 付 服 务 provider8006
cloud-providerconsul-payment8006
POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| <?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> <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> <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>
|
YML
1 2 3 4 5 6 7 8 9 10 11
| server: port: 8006 spring: application: name: consul-provider-payment cloud: consul: host: localhost port: 8500 discovery: service-name: ${spring.application.name}
|
主启动类
1 2 3 4 5 6 7
| @EnableDiscoveryClient @SpringBootApplication public class PaymentMain8006 { public static void main(String[] args) { SpringApplication.run(PaymentMain8006.class, args); } }
|
主业务类 Controller
1 2 3 4 5 6 7 8 9 10 11 12
| @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
POM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <?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> <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> <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>
|
YML
1 2 3 4 5 6 7 8 9 10 11 12
| server: port: 80
spring: application: name: consul-consumer-order cloud: consul: host: localhost port: 8500 discovery: service-name: ${spring.application.name}
|
主启动类
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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); } }
|
配置 Bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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(); } }
|
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 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;
@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) 架构