SpringCloud-概述_服务治理(Eureka_Zookeeper_Consul)
概述
分布式微服务架构的一站式解决方案;
多种微服务架构落地技术的集合体;
https://gitee.com/lixiaogou/cloud2020/tree/master
SpringCload升级
服务治理
why
在传统的RPC(Remote Procedure Call)框架中,管理每个服务与服务之间的依赖关系非常复杂,所以需要服务治理;
作用
管理服务之间的依赖关系,实现服务调用、负载均衡、容错...
实现
Eureka
what
1、SpringCloud封装了Netflix的Eureka实现 服务治理;
2、Eureka采用CS的架构模式:
EurekaServer作为服务注册功能的服务器,它是服务注册中心;
系统中其他微服务,使用EurekaClient连接到EurekaServer 并维持心跳;
服务注册与发现
在服务注册与发现中,有一个注册中心;
当服务提供者启动时,会将自己的服务器信息(服务地址、通讯地址...)以别名的方式注册到注册中心;
服务消费者 可以通过 别名到注册中心获取真实的通讯地址;
最终实现 RPC调用;
Eureka组成
EurekaServer
各个微服务节点通过配置启动后,在EurekaServer中注册;
EurekaServer的注册表 就会存储 所有可用的服务节点信息;
EurekaClient
一个Java客户端;
用于简化与EurekaServer的交互;
具备一个内置的、使用轮询负载算法(round-robin)的负载均衡器;
应用启动后,将会向EurekaServer发送心跳(默认周期30s),如果EurekaServer在多个心跳周期内(默认90s)没有接收到某个节点的心跳,EurekaServer将把其移除;
EurekaServer单机
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> server: port: 7001 # 单机版 eureka: instance: hostname: localhost #eureka服务端的实例名字 client: register-with-eureka: false #表示不向注册中心注册自己 fetch-registry: false #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址 @SpringBootApplication @EnableEurekaServer public class EurekaServer7001 { public static void main(String[] args) { SpringApplication.run(EurekaServer7001.class, args); log.info("EurekaServer7001..."); } }
eureka: client: register-with-eureka: true #是否向注册中心注册自己 fetchRegistry: true #是否从注册中心抓取已有的注册信息 默认true,集群必须设置为true service-url: defaultZone: http://localhost:7001/eureka/ #单机版
EurekaServer集群
微服务RPC的核心是:高可用;
解决方案:EurekaServer集群(实现负载均衡、故障容错);
核心思想:EurekaServer相互注册、相互
server: port: 7001 # 集群版 eureka: instance: hostname: eureka7001.com #eureka服务端的实例名字 client: register-with-eureka: false #表示不向注册中心注册自己 fetch-registry: false #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://eureka7002.com:7002/eureka/ #7001 注册到7002 server: port: 7002 # 集群版 eureka: instance: hostname: eureka7002.com #eureka服务端的实例名字 client: register-with-eureka: false #表示不向注册中心注册自己 fetch-registry: false #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://eureka7001.com:7001/eureka/ #7002 注册到7001
eureka: client: register-with-eureka: true #是否向注册中心注册自己 fetchRegistry: true #是否从注册中心抓取已有的注册信息 默认true,集群必须设置为true service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #集群版
负载均衡
当服务提供者是集群时,需要@LoadBalanced赋予RestTemplate负载均衡的能力(可以通过 统一的服务提供者名称 访问不同的服务实例);
@LoadBalanced // 赋予RestTemplate负载均衡的能力 @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } Controller{ ... restTemplate.postForObject("http://服务提供者统一服务名称" + "/payment/create"...); }
Ribbon和Eureka整合后,Consumer可以直接调用服务(不需要关心地址和端口号)且 服务有负载均衡的能力;
actuator微服务信息完善
eureka: client: register-with-eureka: true #是否向注册中心注册自己 fetchRegistry: true #是否从注册中心抓取已有的注册信息 默认true,集群必须设置为true service-url: defaultZone: http://localhost:7001/eureka/ #单机版 instance: instance-id: payment8002 # 自定义服务名称 prefer-ip-address: true #访问路径显示IP地址
服务发现Discovery
对于注册到EurekaServer的微服务,可以通过DiscoveryClient服务发现来获取该服务的信息;
1、DiscoveryClient注入Bean @Autowired private DiscoveryClient discoveryClient; { ....List<String> services = discoveryClient.getServices(); .... } 启动类 增加 @EnableDiscoveryClient @EnableDiscoveryClient @EnableEurekaClient @SpringBootApplication public class PaymentStarter8001 { public static void main(String[] args) { SpringApplication.run(PaymentStarter8001.class, args); System.out.println("PaymentStarter8001..."); } }
Eureka自我保护机制
概述
{自我保护机制是一种应对网络异常的安全保护措施}
保护机制主要用于 一组EurekaClient与EurekaServer之间 存在网络分区场景下的保护;
一旦进入保护模式,EurekaServer将尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(不注销任何服务);
属于CAP中的AP;
表现
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
why
为了防止 EurekaClient虽然正常运行 但 与EurekaServer网络不通的情况下,EurekaServer不会立刻将EurekaClient剔除;
什么是自我保护机制
默认情况下,EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将注销该实例(默认90s);
但是,当网络分区故障(延时、卡顿、拥挤)发生时,微服务与EurekaServer之间无法正常通信,微服务本身是正常的,此时本不该注销此微服务;
Eureka通过自我保护机制来解决这个问题---当EurekaServer在短时间内丢失客户端时,EurekaServer将进入自我保护模式;
禁止自我保护机制
server.application eureka: server: #关闭自我保护机制 enable-self-preservation: false #关闭自我保护机制(服务不可用时,及时删除) eviction-interval-timer-in-ms: 2000 #清除无效client时间间隔 ---------------------------------------------------------------------- client.application eureka: instance: instance-id: payment8001 prefer-ip-address: true lease-renewal-interval-in-seconds: 1 # EurekaClient向EurekaServer发送心跳的时间间隔(默认30s) lease-expiration-duration-in-seconds: 2 # EurekaServer在收到EurekaClient最后一次心跳后,等待的时间上限(默认90s)
Eureka停更
https://github.com/Netflix/eureka/wiki
Eureka 2.0 (Discontinued)
The existing open source work on eureka 2.0 is discontinued. The code base and artifacts that were released as part of the existing repository of work on the 2.x branch is considered use at your own risk.
Eureka 1.x is a core part of Netflix's service discovery system and is still an active project.
Eureka停止更新怎么办?
SpringCloud整合zookeeper代替Eureka
zookeeper
https://zookeeper.apache.org/releases.html
https://www.runoob.com/w3cnote/zookeeper-tutorial.html
what
zookeeper单机版
provider
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> </dependency> server: port: 8003 spring: application: name: payment-service cloud: # 服务提供者 注册到 zookeeper的地址 zookeeper: connect-string: localhost:2181 @SpringBootApplication @EnableDiscoveryClient // 向 使用consul/zookeeper作为注册中心时 注册服务 public class PaymentStarter8003 { public static void main(String[] args) { SpringApplication.run(PaymentStarter8003.class, args); } }
consumer
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> </dependency> spring: application: name: order-service cloud: # 服务消费者 注册到 zookeeper的地址 zookeeper: connect-string: localhost:2181 @SpringBootApplication @EnableDiscoveryClient // 向 使用consul/zookeeper作为注册中心时 注册服务 public class OrderStarter80 { public static void main(String[] args) { SpringApplication.run(OrderStarter80.class, args); } }
zookeeper节点特性
临时节点(当服务长时间异常,将会移除);
consul
https://www.springcloud.cc/spring-cloud-consul.html
what
一套开源的 分布式服务发现和配置管理系统;
使用go语言开发;
提供了服务治理、配置中心、控制总线等功能(每个功能都可以根据需求单独使用,也可以一起使用);
特性
服务注册与发现、健康检测、k-v存储、多数据中心、可视化web界面
单机版
provider
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> spring: application: name: payment-service cloud: # 服务提供者 注册到 consul consul: host: localhost port: 8500 discovery: service-name: ${spring.application.name} @SpringBootApplication @EnableDiscoveryClient // 向 使用consul/zookeeper作为注册中心时 注册服务 public class PaymentStarter8004 { public static void main(String[] args) { SpringApplication.run(PaymentStarter8004.class, args); } }
consumer
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> spring: application: name: order-service cloud: # 服务消费者 注册到 zookeeper的地址 conusl: host: localhost port: 8500 discovery: service-name: ${spring.application.name} @SpringBootApplication @EnableDiscoveryClient // 向 使用consul/zookeeper作为注册中心时 注册服务 public class OrderStarter80 { public static void main(String[] args) { SpringApplication.run(OrderStarter80.class, args); } }
Eureka-Zookeeper-Consul异同点
cap
c(consistency):强一致性、a(availability):可用性、p(partition tolerance):分区容错性
cap关注的是数据,不是整体系统设计的策略;
AP
AP架构,当网络分区出现后,为了保证分区的可用性,系统B可以返回旧值;
CP
CP架构,当网络分区出现后,为了一致性,系统B必须拒接请求;