SpringCloud - 服务注册中心
文章目录
- 1.服务注册中心
- 2.Eureak服务注册中心
- 2.1 Eureka服务注册与发现
- 2.1.1 单机Eurake构建步骤
- (1) 创建EurekaServer服务注册中心
- (2) EurekaClient服务注册
- 2.1.2 Eureka集群构建步骤
- (1) 创建第多个EureakServer注册中心
- (2) 修改host(模拟)
- (3) 修改YML配置
- 2.1.3 集群配置EurekaClient
- 2.1.4 支付服务payment微服务集群配置
- (1) 创建新生产者
- (2) 消费者开启负载均衡
- 2.2 actuator微服务信息完善
- 2.3 服务发现Discovery
- 2.4 Eureka保护模式
- 2.4.1 概念
- 2.4.2 禁止自我保护
- 3.zookeeper注册中心
- 3.1 注册生产者
- 问题:版本冲突
- 问题:slf4j出现冲突
- 3.2 注册消费者
- 4.Consul注册中心
- 4.1 简介
- 4.2 安装并运行Consul
- 4.3 注册提供者
- 4.4 注册消费者
- 5.三个注册中心的异同点
- 5.1 CAP
- 5.2 AP(EureKa)
- 5.3 CP(Zookeeper/Soncul)
1.服务注册中心
什么是服务治理
Spring cloud 封装了Netflix 公司开发的 Eureka 模块来实现服务治理
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要服务治理,管理服务与服务之间依赖关系,可以实现服务调用,负载均衡,容错等,实现服务发现于注册。
什么是服务注册与发现
Eureka 采用了CS架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心,而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server 并且维持心跳连接,这样系统的维护人员就可以通过Eureka Server 来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心,当服务器启动的时候,会把当 前服务器的信息,比如服务器地址、通讯地址等以别名方式注册到注册中心上,另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC。远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务于服务之间的一个依赖关系(服务治理概念),再任何RPC远程框架中,都会有一个注册中心(存放服务器地址相关信息(接口地址))。
下左图为Eureka 系统架构,右图 是Dubbo的架构
2.Eureak服务注册中心
2.1 Eureka服务注册与发现
Eureka 包含两个组件: Eureka Server 和Eureka Client
Eureka Server 提供服务注册服务
各个服务器节点通过配置启动后,会在EurekaServer 中进行注册,这样EurekaServer 中的服务注册表中将会存储所有可用服务节点信息,服务节点的信息可以再界面中直观看到。
Eureka Client 通过注册中心进行访问
是一个java客户端,用户简化Eureka Server 的交互,客户端同时也具备一个内置的,使用轮询(round-robin)负载算法的负载均衡器,再应用启动后,会将Eureka Server 发生心跳(默认周期30秒)。如果Eureka Server 再多个心跳周期内没有接收到某个节点的心跳,EurekaServer会从服务注册表中把这个服务节点移除(默认90秒)。
2.1.1 单机Eurake构建步骤
(1) 创建EurekaServer服务注册中心
创建模块:
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>cloud2022</artifactId><groupId>com.jm.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-eureka-server7001</artifactId><dependencies><!--eureka-server--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><dependency><groupId>com.jm.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!--boot web actuator--><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>
application.yml文件配置:
server:port: 7001
eureka:instance:hostname: localhost #eureka服务端实例名称client:register-with-eureka: false # false 表示不向注册中心注册自己fetch-registry: false # false 表示自己端就是服务注册中心,我的职责就是维护服务实例,并不需要去检索服务service-url:# 设置于Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动类:
package com.jm.springcloud;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);}
}
启动后访问:http://localhost:7001/
(2) EurekaClient服务注册
EurekaClient端cloud-provider-payment8001将其注册进EurekaServer成为服务提供着provider
1.再pom文件中添加依赖
<!-- 添加Eureka Client 的依赖 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.application.yml中添加配置
eureka:client:# 表示是否将自己注册进EurekaServer 默认为trueregister-with-eureka: true# 是否从EurekaServer 抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配置ribbon使用负载均衡fetch-registry: trueservice-url:# 服务器地址defaultZone: http://localhost:7001/eureka
3.启动类上添加注解
@SpringBootApplication
@EnableEurekaClient // 表示自己是Eureka 的客户端
public class PaymentMain8001{public static void main(String[] args) {SpringApplication.run(PaymentMain8001.class, args);}
}
启动后,再EurekaServer中可以可能到cloud-provider-payment8001服务已经注册完成,并且注册的名称是的该服务的spring.application.name: cloud-payment-service的名称
EurekaClient端cloud-consumer-order80将其注册进EurekaServer成为服务消费者consumer
1.添加pom文件
<!-- 添加Eureka Client 的依赖 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.修改application.yml
server:port: 80spring:application:name: cloud-order-servereureka:client:# 表示是否将自己注册进EurekaServer 默认为trueregister-with-eureka: true# 是否从EurekaServer 抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配置ribbon使用负载均衡fetch-registry: trueservice-url:# 服务器地址defaultZone: http://localhost:7001/eureka
3.启动类上添加@EnableEurekaClient
注解
@SpringBootApplication
@EnableEurekaClient // 表示自己是Eureka 的客户端
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}
}
4.查看注册中心是否已经注册成功
2.1.2 Eureka集群构建步骤
微服务RPC远程服务的核心是什么:高可用**
搭建Eureka注册中心集群,实现负载均衡+故障容错
EurekaServer:服务注册:将服务信息注册进注册中心,服务发现:从注册中心上获取服务信息,实质:存Key服务名称,取value调用地址
服务的启动说明:
- 先启动EurekaServer注册中心
- 启动服务提供者Payment支付服务
- 支付服务启动后会把自身信息(比如服务地址以别名的方式注册进Eureka)
- 消费者order服务需要调用接口时,使用服务别名取注册中心获取实际的RPC远程调用地址
- 消费者获取地址后,底层实际是利用httpClient技术实现远程调用
- 消费者获取服务地址后会缓存到本地jvm内存中,默认每间隔30秒更新一次服务调用地址
(1) 创建第多个EureakServer注册中心
创建cloud-eureka-server7002
创建方式参考单机版EurekaServer,这里不再重复记录
(2) 修改host(模拟)
因为我们是单机上进行模拟,所以我们修改host来达到访问两台机器的效果
打开:C:\Windows\System32\drivers\etc\hosts,添加上:
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
(3) 修改YML配置
cloud-eureka-server7001的yml配置:
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/ # 服务注册中心互相守注册
cloud-eureka-server7002的yml配置:
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/ # 服务注册中心互相守注册
启动后可以在看到
http://eureka7001.com:7001/ 中看到erueka7002被注册进入
http://eureka7002.com:7002/ 中看到erueka7001被注册进去
表示EurekaServer集群搭建成功!!!/!!!/!!!
2.1.3 集群配置EurekaClient
将支付服务8001微服务发布到上面的EurekaServer集群配置中
修改yml配置文件:
# 是否从EurekaServer 抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配置ribbon使用负载均衡fetch-registry: trueservice-url:# 服务器地址#defaultZone: http://localhost:7001/eureka # 单机版defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 注册到集群中去
将订单服务80微服务发布到上面的EurekaServer集群配置中
修改yml配置文件:
# 是否从EurekaServer 抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配置ribbon使用负载均衡fetch-registry: trueservice-url:# 服务器地址#defaultZone: http://localhost:7001/eureka # 单机版defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 注册到集群中去
测试流程
- 启动EurekaServer集群
- 再启动服务生产者provider,8001
- 再启动消费者80
- 访问 http://localhost:80/consumer/payment/2
测试:
能够在http://eureka7002.com:7002/和http://eureka7001.com:7001/中看到内容表示成功
访问消费者:http://localhost:80/consumer/payment/2
2.1.4 支付服务payment微服务集群配置
配置多个生产者微服务端供其消费端进行使用
(1) 创建新生产者
创建cloud-provider-payment8002模块
配置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>cloud2022</artifactId><groupId>com.jm.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-provider-payment8002</artifactId><dependencies><!-- 添加Eureka Client 的依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><artifactId>cloud-api-commons</artifactId><groupId>com.jm.springcloud</groupId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--使用 spring-boot-starter-actuator 可以用于检测系统的健康情况、当前的Beans、系统的缓存等--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency><!--mysql connector -java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</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-test</artifactId><scope>test</scope></dependency></dependencies></project>
application.yml拷贝(修改端口)
server:port: 8002spring:application:name: cloud-payment-servicedatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: rootpassword: 021107mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.jm.springcloud.entities # 所有Entity别名坐在的包configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpleureka:client:# 表示是否将自己注册进EurekaServer 默认为trueregister-with-eureka: true# 是否从EurekaServer 抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配置ribbon使用负载均衡fetch-registry: trueservice-url:#defaultZone: http://localhost:7001/eureka # 单机版defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 注册到集群中去
业务代码直接拷贝cloud-provider-payment8001
给cloud-provider-payment8001和cloud-provider-payment8002的Conttoller 添加代码来区分使用的是哪一个子模型:
@Value("${server.port}")private String serverPort;
逐一启动后查看EurekaServer是否配置成功
(2) 消费者开启负载均衡
在cloud-consumer-order80的Controller中,restTemplate不在访问的是具体的ip+端口名称,而是访问EurekaServer中注册的服务名称
@RestController
@Slf4j
@RequestMapping("/consumer")
public class OrderController {// public static final String URL = "http://localhost:8001";public static final String URL = "http://CLOUD-PAYMENT-SERVICE"; // 使用的是EurekaServer中注册中心的服务名称@Resourceprivate RestTemplate restTemplate;@GetMapping("/payment/create")public CommonResult<Payment> create(Payment payment) {return restTemplate.postForObject(URL + "/payment/", payment, CommonResult.class);}@GetMapping("/payment/{id}")public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {return restTemplate.getForObject(URL + "/payment/" + id, CommonResult.class);}
}
并且使用@LoadBalanced
注解赋予RestTemplate负载均衡的能力(默认轮询)
@Configuration
public class ApplicationContextConfig {@LoadBalanced // 赋予RestTemplate负载均衡的能力@Beanpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}
2.2 actuator微服务信息完善
主机/服务器名称修改
修改cloud-provider-payment8001的YML文件:添加配置
eureka:instance:instance-id: payment8001 # 主机名称
修改cloud-provider-payment8002的YML文件:添加配置
eureka:instance:instance-id: payment8002 # 主机名称
修改完成后将看到EurekaServer中主机名称已经被修改了
访问信息有IP信息提示
左下角不显示IP地址
修改cloud-provider-payment8001、cloud-provider-payment8002的YML文件:添加配置
eureka:instance:prefer-ip-address: true # 显示ip地址
2.3 服务发现Discovery
对于注册进Eureka里面的微服务,可以通过服务发现来获得服务的信息
在cloud-payment-server8001的启动类上添加注解@EnableDiscoveryClient
开启服务发现
@SpringBootApplication
@EnableEurekaClient // 表示自己是Eureka 的客户端
@EnableDiscoveryClient // 自动配置服务发现
public class PaymentApplication8001 {public static void main(String[] args) {SpringApplication.run(PaymentApplication8001.class, args);}
}
在Controller中获取DiscoveryClient实例从而服务信息
@Resourceprivate DiscoveryClient discoveryClient; // 服务发现客户端@GetMapping("/discovery")public Object getDiscovery() {// 获取EurekaServer上的所有服务List<String> services = discoveryClient.getServices();services.forEach(log::info);// 通过服务名称获取实例List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");for (ServiceInstance instance : instances) {log.info("服务名称:{} ip地址:{} 端口号:{} url地址:{}", instance.getServiceId(),instance.getHost(), instance.getPort(), instance.getUri());}return discoveryClient;}
2.4 Eureka保护模式
2.4.1 概念
保护模式主要是用于一组客户端和Eureka Server之间存在网络分区场景下的保护,一旦进入保护 模式,EurekaServer将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务
如果在Eureka Server的首页看到以下这段提示,则说明Eureka进入了保护模式
一句话:某个时刻某个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存
属于CAP里面的AP分支
为什么会产生Eureka自我保护机制?
为了防止EurekaClient可以正常运行,但是与EurekaServer网络不通情况下,EurekaServer不会立刻将EurekaClient服务剔除
什么是自我保护机制?
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生(延时、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。
一句话讲解:好死不如赖活着
综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定
2.4.2 禁止自我保护
- 在cloud-eureka-server7001端中去设置关闭自我保护机制
eureka:instance:hostname: eureka7001.com #eureka服务端实例名称client:register-with-eureka: false # false 表示不向注册中心注册自己fetch-registry: false # false 表示自己端就是服务注册中心,我的职责就是维护服务实例,并不需要去检索服务service-url:# 集群指向其他eurekaServer服务器
# defaultZone: http://eureka7002.com:7002/eureka/ # 服务注册中心互相守注册# 单机就是自己defaultZone: http://eureka7001.com:7001/eureka/ # 服务注册中心互相守注册server:# 关闭自我保护机制,保证不可用服务及时被剔除enable-self-preservation: false# 收回间隔时间2秒,当两秒内没恢复心跳将剔除eviction-interval-timer-in-ms: 2000
红字表示已经关闭了保护模式
- 修改cloud-provider-payment8001的配置:
eureka:client:# 表示是否将自己注册进EurekaServer 默认为trueregister-with-eureka: true# 是否从EurekaServer 抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配置ribbon使用负载均衡fetch-registry: trueservice-url:defaultZone: http://localhost:7001/eureka # 单机版# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 注册到集群中去instance:instance-id: payment8001 # 主机名称prefer-ip-address: true # 显示ip地址# 心跳检测与续约时间# 开发时设置小些,保证服务关闭后注册中心能及时剔除服务# Eureka客户端向服务器发送心跳的时间间隔,单位秒(默认30秒)lease-renewal-interval-in-seconds: 1# Eureka 服务端在收到最后一次心跳后等待时间上限,单位秒(默认是90秒),超时将剔除lease-expiration-duration-in-seconds: 2
- 启动注册到EurekaServer中后,在将cloud-provider-payment8001服务停止,将看到服务在2秒内被剔除出了注册表
3.zookeeper注册中心
zookeeper是一个分布式协调工具,可以实现注册中心功能
zookeeper中,服务都是临时节点的方式存在着。当一定时间内接收不到服务的心跳,将会把该服务移除,若重新接收到了服务的心跳是会在重新生成一个编码,而不是使用直接的编码
3.1 注册生产者
pom文件:
注意:这里实验的是如何使用zookeeper作为服务注册中心,所以不再使用dao
<?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>cloud2022</artifactId><groupId>com.jm.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-provider-payment8004</artifactId><dependencies><!-- SpringBoot整合Web组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><groupId>com.jm.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></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-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>
application.yml
server:port: 8004# 服务别名-------注册zookeeper到注册中心名称
spring:application:name: cloud-provider-paymentcloud:zookeeper:connect-string: 192.168.36.100:2181 # zookeeper server 单机的地址
主启动类
package com.jm.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient // 该注解用于向使用 consul 或者 zookeeper 作为注册中心是注册服务
public class PaymentApplication8004 {public static void main(String[] args) {SpringApplication.run(PaymentApplication8004.class, args);}
}
业务逻辑类
package com.jm.springcloud.controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.util.UUID;@Slf4j
@RestController
@RequestMapping("/payment")
public class PaymentController {@Value("${server.port}") // 获取当前项目的端口private String port;@GetMapping("/zk")public String paymentzk(){return " spring cloud with zookeeper : " + port + "\t" + UUID.randomUUID().toString();}
}
启动服务,查看 zookeeper客户端情况,会发现服务以及注册到zookeeper中
调用接口:http://localhost:8004/payment/zk
问题:版本冲突
依赖包与服务器的Zookeeper版本冲突,修改jar版本
<!-- Spring boot 整合zookeeper 客户端 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zookeeper-discovery</artifactId><!-- 先排除自带的zookeeper3.5.3 --><exclusions><exclusion><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></exclusion></exclusions></dependency><!-- 添加 zookeeper 3.4.9 依赖 --><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.9</version></dependency>
问题:slf4j出现冲突
给zookeeper排除slf4j依赖
<!-- 添加 zookeeper 3.4.9 依赖 --><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.9</version><!--解决 Class path contains multiple SLF4J bindings. 问题 --><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency>
3.2 注册消费者
创建模块:
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>cloud2022</artifactId><groupId>com.jm.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-consumerzk-order80</artifactId><dependencies><!-- SpringBoot整合Web组件 --><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-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>
application.yml文件
server:port: 80# 服务别名-------注册zookeeper到注册中心名称
spring:application:name: cloud-consumerzk-ordercloud:zookeeper:connect-string: 192.168.36.100:2181 # zookeeper server 单机的地址
主启动类
@SpringBootApplication
@EnableDiscoveryClient
public class ZkOrder80Application {public static void main(String[] args) {SpringApplication.run(ZkOrder80Application.class, args);}
}
配置类
@Configuration
public class ApplicationContextConfig {@Bean@LoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}
业务类
@RestController
@RequestMapping("/consumer")
public class OrderZkController {// 这里使用的是zookeeper中注册的服务地址名称public static final String INVOKE_URL = "http://cloud-provider-payment";@Resourceprivate RestTemplate restTemplate;@GetMapping("/consumer/payment/zk")public String paymentInfo() {return restTemplate.getForObject(INVOKE_URL + "/payment/zk", String.class);}}
启动,查看zookeeper客户端:
消费者以及被注册进去了,并且调用接口:http://localhost/consumer/payment/zk,成功调用服务
4.Consul注册中心
4.1 简介
官网地址:https://www.consul.io/docs/intro
提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案。
Consul提供的功能:
- 服务发现:提供HTTP和DNS两种发现方式。
- 健康检测:支持多种方式,HTTP、TCP、Docker、Shell脚本定制化
- KV存储: Key、Value的存储方式
- 多数据中心:Consul支持多数据周秀娜
- 可视乎WEB界面
教程: https://www.springcloud.cc/spring-cloud-consul.html
4.2 安装并运行Consul
下载地址:https://www.consul.io/downloads
本次使用的是windows版本,下载完成解压后之后一个consul.exe文件,
查看版本:consul --version
使用开发者模式启动:consul agent -dev
通过以下地址可以访问Consul的首页:http://localhost:8500/
4.3 注册提供者
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>cloud2022</artifactId><groupId>com.jm.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-providerconsul-payment8006</artifactId><dependencies><!--SpringCloud consul-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><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
###consul服务端口号
server:port: 8006spring:application:name: consul-provider-payment####consul注册中心地址cloud:consul:host: localhostport: 8500discovery:#hostname: 127.0.0.1service-name: ${spring.application.name}
启动类:
package com.jm.springcloud;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);}}
业务类:
package com.jm.springcloud.controller;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;@RestController
public class PaymentController {@Value("${server.port}")private String serverPort;@GetMapping("/payment/consul")public String paymentInfo(){return "springcloud with consul: "+serverPort+"\t\t"+ UUID.randomUUID().toString();}}
启动该访问后,在consul 客户端发现服务以及注册到了consul中
访问接口也正常
4.4 注册消费者
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>cloud2022</artifactId><groupId>com.jm.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-consumerconsul-order80</artifactId><dependencies><!--SpringCloud consul-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><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
###consul服务端口号
server:port: 80spring:application:name: cloud-consumer-order####consul注册中心地址cloud:consul:host: localhostport: 8500discovery:#hostname: 127.0.0.1service-name: ${spring.application.name}
启动类
package com.jm.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);}}
配置类
package com.jm.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 ApplicationContextBean {@Bean@LoadBalancedpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}
业务类
package com.jm.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 INVOKE_URL="http://consul-provider-payment";@Resourceprivate RestTemplate restTemplate;@GetMapping("/consumer/payment/consul")public String paymentInfo(){String result = restTemplate.getForObject(INVOKE_URL + "/payment/consul", String.class);return result;}
}
启动该服务,查看consul客户端,消费者服务以及注册成功
访问接口也是成功的
5.三个注册中心的异同点
5.1 CAP
CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
- 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
- 可用性(A):保证每个请求不管成功或者失败都有响应。
- 分区容忍性(P):系统中任意信息的丢失或失败不会影响系统的继续运作。
CAP理论的核心:一个分布式系统不可能同时很好的满足一致性,可用性、分区容错性者三个需求。
CAP理论关注粒度是数据,而不是整体系统设计的策略
因此,根据CAP原理将NoSQL数据库分成了满足CA原则、满足CР原则和满足AP原则三大类:
CA-单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP-满足—致性,分区容忍必的系统,通常性能不是特别高。
AP -满足可用性,分区容忍性的系统,通常可能对—致性要求低一些。
5.2 AP(EureKa)
当网络分区出现后,为了保证可用性(A),系统B可以返回旧值,保证系统的可用性。
结论:违背了一致性©的要求,只满足可用性和分区容错,即AP
5.3 CP(Zookeeper/Soncul)
当网络分区出现后,为了保证一致性© 就必须拒绝请求,否则无法保证一致性
结论:违背了可用性(A)的要求,只满足了一致性和分区容错,即CP
SpringCloud - 服务注册中心相关推荐
- springcloud服务注册中心eureka搭建
pom.xml依赖: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...
- SpringCloud + Consul服务注册中心 + gateway网关
1 启动Consul 2 创建springcloud-consul项目及三个子模块 2.1 数据模块consul-producer 2.2 数据消费模块consul-consumer 2.3 ga ...
- 史上最简单的SpringCloud教程 | 第十篇: 高可用的服务注册中心
转自:https://blog.csdn.net/forezp/article/details/81041101 文章 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eu ...
- Eureka服务注册中心---SpringCloud
Eureka服务注册中心 5.1 什么是Eureka Netflix在涉及Eureka时,遵循的就是API原则. Eureka是Netflix的有个子模块,也是核心模块之一.Eureka是基于REST ...
- 【SpringCloud】 第十篇: 高可用的服务注册中心
前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...
- 如何使用 SpringCloud 搭建服务注册中心?
作者 | 于海东 责编 | 郭 芮 之前在巧玩SpringBoot--SpringBoot的第一个"Hello World!"(https://blog.csdn.net/do ...
- SpringCloud系列(一)、服务注册中心Eureka基础
启动Eureka服务注册中心 1.微服务的注册中心 1.1.注册中心的主要作用 1.2.常见的注册中心 1.3.常见注册中心的异同点 2.Eureka概述 2.1.Eureka的基础知识 2.2.Eu ...
- 巧玩SpringCloud——使用Eureka搭建服务注册中心与服务发现
转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/84549747 本文出自[我是干勾鱼的博客] Ingredient: Java:J ...
- SpringCloud 搭建服务注册中心
SpringCloud 搭建服务注册中心 原创 作者 | 于海东 之前在巧玩SpringBoot--SpringBoot的第一个"Hello World!"(https://blo ...
最新文章
- 奇葩错误:不同变量名称相同
- 【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)
- 为什么vue前端项目要使用nodejs
- 2009从知到行知识管理培训公开课最后一期
- OpenMap教程5 – 3层GIS应用程序
- Android硬件入门-照相机
- php乱码解决方案,PHP中文乱码解决方案
- 4400元起!iPhone 12全系售价曝光:标配数据线但无充电器
- 【hortonworks/registry】诡异问题之启动了却无法访问
- EXCEL中如何撤销工作表保护
- wifi-sdio接口
- GEE拼接字符串出错,原因是忘了加getInfo()
- 18-Sqoop、DataX和Azkaban的介绍
- 简单爬取网易云音乐评论(新手报到)
- 相见恨晚 -- 彭佳慧
- JS-修改图片颜色值
- latex在参考文献表中不输出网址和doi
- 二、jQuery 选择器(超细)
- php怎么实现根据图片搜索图片功能
- (P9)awk:什么是awk,awk简单用法,awk脚本语法,awk执行过程