15.Eureka基础知识
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))

16.EurekaServer服务端安装
- 建module 
- 改pom 
- 写yml 
- 主启动 
- 业务类 
1.建名为cloud-eureka-server7001的module
2.修改pom文件
| 12
 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>springcloud</artifactId>
 <groupId>com.yxz.springcloud</groupId>
 <version>1.0-SNAPSHOT</version>
 </parent>
 <modelVersion>4.0.0</modelVersion>
 
 <artifactId>cloud-eureka-server7001</artifactId>
 
 <dependencies>
 
 <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
 </dependency>
 
 <dependency>
 <groupId>com.yxz.springcloud</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>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
 </dependency>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 </dependency>
 </dependencies>
 </project>
 
 | 
3.写yml文件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | 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/
 
 | 
4.主启动,添加@EnableEurekaServer
| 12
 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.netflix.eureka.server.EnableEurekaServer;
 
 @SpringBootApplication
 @EnableEurekaServer
 public class EurekaMain7001 {
 public static void main(String[] args) {
 SpringApplication.run(EurekaMain7001.class, args);
 }
 }
 
 
 | 
5.运行

17.支付微服务8001入驻进eurekaServer
- 改module 
- 改pom 
- 写yam 
- 主启动 
- 业务类 
1.修改
2.改pom
添加eureka-client依赖
| 12
 3
 4
 5
 
 |  <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>
 
 | 
3.写yml
| 12
 3
 4
 5
 6
 7
 8
 
 | eureka:client:
 
 register-with-eureka: true
 
 fetch-registry: true
 service-url:
 defaultZone: http://localhost:7001/eureka
 
 | 
4.主启动
| 12
 3
 4
 5
 6
 7
 
 | @EnableEurekaClient  @SpringBootApplication
 public class PaymentMain8001 {
 public static void main(String[] args) {
 SpringApplication.run(PaymentMain8001.class, args);
 }
 }
 
 | 
5.运行
成功注册服务

18.支付微服务80入驻EurekaServer
1.改cloud-consumer-order80模块
2.改pom
添加eureka-client依赖
| 12
 3
 4
 5
 
 |  <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>
 
 | 
3.写yml
| 12
 3
 4
 5
 6
 7
 8
 
 | eureka:client:
 
 register-with-eureka: true
 
 fetch-registry: true
 service-url:
 defaultZone: http://localhost:7001/eureka
 
 | 
4.主启动
| 12
 3
 4
 5
 6
 7
 
 | @EnableEurekaClient  @SpringBootApplication
 public class PaymentMain80 {
 public static void main(String[] args) {
 SpringApplication.run(PaymentMain80.class, args);
 }
 }
 
 | 
5.运行
先启动cloud-eureka-server7001,后启动80和8001,通过访问80,成功调用。
19. Eureka集群原理说明

问题:微服务RPC远程服务调用最核心的是什么
高可用,试想你的注册中心只有一个only one, 它出故障了那就呵呵( ̄▽ ̄)”了,会导致整个为服务环境不可用,所以
解决办法:搭建Eureka注册中心集群 ,实现负载均衡+故障容错
互相注册,相互守望。
20. Eureka集群环境构建
创建cloud-eureka-server7002工程,参考16.EurekaServer服务端安装
- 找到C:\Windows\System32\drivers\etc路径下的hosts文件,修改映射配置添加进hosts文件
| 12
 3
 
 | #########springcloud2020########127.0.0.1 eureka7001.com
 127.0.0.1 eureka7002.com
 
 | 
- 修改cloud-eureka-server7001的yml配置文件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | server:port: 7001
 eureka:
 instance:
 hostname: eureka7001.com
 client:
 
 register-with-eureka: false
 
 fetch-registry: false
 service-url:
 
 defaultZone: http://eureka7002.com:7002/eureka/
 
 | 
- 修改cloud-eureka-server7002的yml配置文件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | server:port: 7002
 eureka:
 instance:
 hostname: eureka7002.com
 client:
 
 register-with-eureka: false
 
 fetch-registry: false
 service-url:
 
 defaultZone: http://eureka7001.com:7001/eureka/
 
 | 
21. 订单支付两个微服务注册进Eureka集群
| 12
 3
 4
 5
 6
 7
 8
 
 | eureka:client:
 
 register-with-eureka: true
 
 fetchRegistry: true
 service-url:
 defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
 
 | 
22.支付微服务集群配置
参考cloud-provider-payment8001的新建
1.建cloud-provider-payment8002的module
2.改pom
3.写yml
4.主启动
5业务类
修改8001/8002的Controller,添加serverPort
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | @Value("${server.port}")private String serverPort;
 
 @PostMapping()
 public CommonResult create(@RequestBody Payment payment) {
 int result = paymentService.create(payment);
 log.info("***********插入结果:" + result);
 if (result > 0) {
 return new CommonResult(200, "插入数据库成功, serverPort : " + serverPort, result);
 } else {
 return new CommonResult(444, "插入数据库失败, serverPort : " + serverPort, null);
 }
 }
 
 @GetMapping("/{id}")
 public CommonResult getById(@PathVariable("id") Long id) {
 Payment payment = paymentService.getPaymentById(id);
 log.info("*******查询结果" + payment);
 if (payment != null) {
 return new CommonResult(200, "查询成功, serverPort : " + serverPort, payment);
 } else {
 return new CommonResult(444, "没有ID = " + id + " 的对应记录, serverPort : " + serverPort, null);
 }
 }
 
 | 
测试
发现无法实现负载均衡,原因:80服务中的controller层把请求的端口写死了,修改为服务名称
| 12
 3
 4
 5
 
 | public class OrderController {
 
 public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
 }
 
 | 
测试
发现报错,这是因为没有添加负载均衡策略的注解
| 12
 3
 4
 5
 6
 7
 
 | @Configurationpublic class ApplicationConfig {
 @Bean
 @LoadBalanced
 public RestTemplate getRestTemplate() {
 }
 }
 
 | 
测试:负载均衡效果达到,8001/8002端口交替出现
23.actuator微服务信息完善
我们希望在eureka主页
修改8001和8002的yml文件
| 12
 3
 4
 
 | eureka:instance:
 instance-id: payment8001
 prefer-ip-address: true
 
 | 
24.服务发现Discovery
需求:提供一个接口,供访问者查询注册进eureka里面的微服务有哪些,包括详细信息。
- 修改cloud-provider-payment8001的Controller
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | @Slf4j@RestController
 @RequestMapping("/payment")
 public class PaymentController {
 
 ···
 
 @Resource
 private DiscoveryClient discoveryClient;
 
 ···
 
 @GetMapping("/services")
 public Object discovery() {
 List<String> services = discoveryClient.getServices();
 for (String service : services) {
 log.info(service);
 }
 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;
 }
 }
 
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | @EnableDiscoveryClient   @EnableEurekaClient
 @SpringBootApplication
 public class PaymentMain8001 {
 public static void main(String[] args) {
 SpringApplication.run(PaymentMain8001.class, args);
 }
 }
 
 
 | 
测试
浏览器输出

控制台打印

25.Eureka自我保护理论
导致原因
一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存。
属于CAP里面的AP分支。
为了防止EurekaClient可以正常运行,但是 与 EurekaServer网络不通情况下,EurekaServer不会立刻将EurekaClient服务剔除
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生(延时、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。
简单的来说,微服务需要定时向Eureka发送消息表示自己还活着(能提供服务),但是由于某些原因,本该发送的确认消息迟迟没有到达Eureka,此时开启自我保护模式的Eureka会选择保留这个服务一段时间(默认90s),没看起自我保护的Eureka会在注册中心删除掉这个微服务
26.禁用自我保护
这里只做学习记录,我自己项目并没有设置!!
- 在eurekaServer端7001处设置关闭自我保护机制
出厂默认,自我保护机制是开启的
使用eureka.server.enable-self-preservation = false可以禁用自我保护模式
| 12
 3
 4
 5
 6
 
 | eureka:server:
 
 enable-self-preservation: false
 eviction-interval-timer-in-ms: 2000
 
 
 | 
关闭效果:
访问7001端口,Eureka会显示:THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
默认:
eureka.instance.lease-renewal-interval-in-seconds=30
eureka.instance.lease-expiration-duration-in-seconds=90
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | eureka:instance:
 instance-id: payment8001
 prefer-ip-address: true
 
 
 
 lease-renewal-interval-in-seconds: 1
 
 lease-expiration-duration-in-seconds: 2
 
 
 | 
- 测试 - 
- 7001和8001都配置完成 
- 先启动7001再启动8001 
 
结果:先关闭8001,马上被删除了
27.Eureka停更
https://github.com/Netflix/eureka/wiki
选用zookeeper代替eureka
28.支付服务注册进zookeeper
zookeeper安装在虚拟机,记得启动zookeeper的服务
加入zookeeper安装目录的bin目录下,执行./zkServer.sh start启动服务,./zkServer.sh status查看状态,显示standalone即启动成功。

1.新建cloud-consumerzk-order80
2.POM
| 12
 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
 
 | <?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>springcloud</artifactId>
 <groupId>com.yxz.springcloud</groupId>
 <version>1.0-SNAPSHOT</version>
 </parent>
 <modelVersion>4.0.0</modelVersion>
 
 <artifactId>cloud-provider-payment8004</artifactId>
 
 <dependencies>
 
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
 <groupId>com.yxz.springcloud</groupId>
 <artifactId>cloud-api-commons</artifactId>
 <version>${project.version}</version>
 </dependency>
 
 <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-zookeeper-discovery</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
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | server:
 port: 8004
 
 spring:
 application:
 name: cloud-provider-payment
 cloud:
 zookeeper:
 connect-string: 192.168.20.128:2181
 
 | 
4.主启动
| 12
 3
 4
 5
 6
 7
 8
 
 | @SpringBootApplication@EnableDiscoveryClient
 public class PaymentMain8004 {
 public static void main(String[] args) {
 SpringApplication.run(PaymentMain8004.class, args);
 }
 }
 
 
 | 
5.业务类
controller
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | @RestController@RequestMapping("/payment")
 public class PaymentController {
 @Value("${server.port}")
 private String serverPort;
 
 @RequestMapping(value = "/zk")
 public String paymentzk()
 {
 return "springcloud with zookeeper: "+serverPort+"\t"+ UUID.randomUUID().toString();
 }
 }
 
 
 | 
6.测试
启动zookeeper客户端。
请求超时的检查一下yml中的ip有没有改
发现报错,愿意是zookeeper版本号冲突,导入新的pom。如果本机zookeeper版本高,有可能不会报错。
| 12
 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
 
 | <?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>springcloud</artifactId>
 <groupId>com.yxz.springcloud</groupId>
 <version>1.0-SNAPSHOT</version>
 </parent>
 <modelVersion>4.0.0</modelVersion>
 
 <artifactId>cloud-provider-payment8004</artifactId>
 
 <dependencies>
 
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
 <groupId>com.yxz.springcloud</groupId>
 <artifactId>cloud-api-commons</artifactId>
 <version>${project.version}</version>
 </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-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>
 
 | 
7.再次测试
成功访问http://localhost:8004/payment/zk
29.临时还是持久节点
ZooKeeper的服务节点是临时节点

30.订单服务注册进zookeeper
1.新建cloud-consumerzk-order80
2.改pom
| 12
 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>springcloud</artifactId>
 <groupId>com.yxz.springcloud</groupId>
 <version>1.0-SNAPSHOT</version>
 </parent>
 <modelVersion>4.0.0</modelVersion>
 
 <artifactId>cloud-consummerzk-order80</artifactId>
 
 <dependencies>
 
 <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-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
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | server:port: 80
 
 spring:
 application:
 name: cloud-consumer-order
 cloud:
 
 zookeeper:
 connect-string: 192.168.20.128:2181
 
 
 | 
4.主启动
| 12
 3
 4
 5
 6
 7
 
 | @SpringBootApplication@EnableDiscoveryClient
 public class OrderZKMain80 {
 public static void main(String[] args) {
 SpringApplication.run(OrderZKMain80.class, args);
 }
 }
 
 | 
5.写业务
配置类
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | package com.yxz.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 ApplicationContextConfig {
 @Bean
 @LoadBalanced
 public RestTemplate getRestTemplet() {
 return new RestTemplate();
 }
 }
 
 
 | 
controller类
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | package com.yxz.springcloud.controller;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
 
 @RestController
 @RequestMapping("/consumer")
 @Slf4j
 public class OrderZKController {
 public static final String INVOKE_URL = "http://cloud-provider-payment";
 
 @Resource
 private RestTemplate restTemplate;
 
 @GetMapping("/payment/zk")
 public String paymentInfo() {
 return restTemplate.getForObject(INVOKE_URL + "/payment/zk", String.class);
 }
 }
 
 
 | 
6.测试
成功

31-32.Consul简介、安装和运行
官网Consul | HashiCorp Developer
win下载64位解压双击.exe文件后,打开cmd
运行consul -v查看版本号,consul agent -dev启动开发者模式

浏览器输入 - http://localhost:8500/ - 打开Consul控制页。
33.服务提供者注册进consul
1.建cloud-providerconsul-payment8006
2.改pom
| 12
 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
 
 | <?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>springcloud</artifactId>
 <groupId>com.yxz.springcloud</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>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
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | server:
 port: 8006
 
 spring:
 application:
 name: consul-provider-payment
 
 cloud:
 consul:
 host: localhost
 port: 8500
 discovery:
 
 service-name: ${spring.application.name}
 
 
 
 
 | 
4.主启动
| 12
 3
 4
 5
 6
 7
 8
 
 | @SpringBootApplication@EnableDiscoveryClient
 public class PaymentMain8006 {
 public static void main(String[] args) {
 SpringApplication.run(PaymentMain8006.class, args);
 }
 }
 
 
 | 
5.业务类
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | package com.yxz.springcloud.controller;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.UUID;
 
 @RestController
 @RequestMapping("/payment")
 public class PaymentController
 {
 @Value("${server.port}")
 private String serverPort;
 
 @GetMapping("/consul")
 public String paymentInfo()
 {
 return "springcloud with consul: "+serverPort+"\t\t"+ UUID.randomUUID().toString();
 }
 }
 
 | 
6.测试
成功

34.服务消费者注册进consul
1.建cloud-consumerconsul-order80
2.改pom
| 12
 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
 
 | <?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>springcloud</artifactId>
 <groupId>com.yxz.springcloud</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>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
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | server:
 port: 80
 
 spring:
 application:
 name: cloud-consumer-order
 
 cloud:
 consul:
 host: localhost
 port: 8500
 discovery:
 
 service-name: ${spring.application.name}
 
 
 | 
4.主启动
| 12
 3
 4
 5
 6
 7
 8
 
 | @SpringBootApplication@EnableDiscoveryClient
 public class OrderConsulMain80 {
 public static void main(String[] args) {
 SpringApplication.run(OrderConsulMain80.class, args);
 }
 }
 
 
 | 
5.业务类
配置类
| 12
 3
 4
 5
 6
 7
 8
 
 | @Configurationpublic class ApplicationContextBean {
 @Bean
 @LoadBalanced
 public RestTemplate getRestTemplate() {
 return new RestTemplate();
 }
 }
 
 | 
controller
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | @RequestMapping("/consumer")@RestController
 public class OrderConsulController {
 
 public static final String INVOKE_URL = "http://consul-provider-payment";
 @Resource
 private RestTemplate restTemplate;
 
 @GetMapping("/payment/consul")
 public String paymentInfo() {
 String forObject = restTemplate.getForObject(INVOKE_URL + "/payment/consul", String.class);
 System.out.println("消费者调用支付服务(consule)--->result:" + forObject);
 return forObject;
 }
 }
 
 | 
6.测试
http://localhost/consumer/payment/consul

35.三个注册中心的异同点
| 组件名 | 语言CAP | 服务健康检查 | 对外暴露接口 | Spring Cloud集成 | 
| Eureka | Java | AP | 可配支持 | HTTP | 
| Consul | Go | CP | 支持 | HTTP/DNS | 
| Zookeeper | Java | CP | 支持客户端 | 已集成 | 
CAP:

最多只能同时较好的满足两个。
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求。
因此,根据CAP原理将NoSQL数据库分成了满足CA原则、满足CP原则和满足AP原则三大类:
- CA - 单点集群,满足—致性,可用性的系统,通常在可扩展性上不太强大。 
- CP - 满足一致性,分区容忍必的系统,通常性能不是特别高。 
- AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些 
到此已经学习完cloud课程的25.65%内容,和前七章节的内容
