注册中心合集(Eureka、Ribbon、Consul)
1.概念
注册中心作为微服务框架的通讯录,记录了服务和服务地址的映射关系。
在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。
2.常见的注册中心
- Netflix Eureka
- HashiCorp Consul
- Apache ZooKeeper
- Ribbon
3. CAP 原则与 BASE 理论
3.1CAP 原则
CAP 原则又称 CAP 定理,指的是在一个分布式系统中,
Consistency(一致性)、
Availability(可用性)、
Partition tolerance(分区容错性),
三者不可得兼。
3.2 BASE 理论
全称 Basically Available(基本可用),Sox state(软状态),和 Eventuallyconsistent(最终一致性)三个短语的缩写,来自 ebay 的架构师提出。
4.注册中心使用价值
4.1 需要考虑的问题
- 服务注册后,如何被及时发现
- 服务宕机后,如何及时下线
- 服务如何有效的水平扩展
- 服务发现时,如何进行路由
- 服务异常时,如何进行降级
- 注册中心如何实现自身的高可用
4.2 注册中心解决了
- 服务管理
- 服务之间的自动发现
- 服务的依赖关系管理
5.Eureka
5.1 概念
Netflix 开发的服务发现组件,基于REST服务。
Spring Cloud 将它集成在其子项目 Spring Cloud Netflix 中,
实现 Spring Cloud 的服务注册与发现,同时还提供了负载均衡、故障转移等能力。
5.2三种角色(两种角色)
- Eureka Server:通过 Register、Get、Renew 等接口提供服务的注册和发现。
- Service Provider(Eureka Client):服务提供方,把自身的服务实例注册到 Eureka Server 中。
- Service Consumer(Eureka Client):服务调用方,通过 Eureka Server 获取服务列表,消费服务。
两种角色的时候,服务消费者和服务提供者中间的存在着一定的练习,可以一并放在Eureka Client中。
5.3 Eureka架构原理
- Register(服务注册):把自己的 IP 和端口注册给 Eureka。
- Renew(服务续约):发送心跳包,每 30 秒发送一次,告诉Eureka 自己还活着。如果 90 秒还未发送心跳,宕机。
- Cancel(服务下线):当 Provider 关闭时会向 Eureka 发送消息,把自己从服务列表中删除。防止Consumer 调用到不存在的服务。
- Get Registry(获取服务注册列表):获取其他服务列表。
- Replicate(集群中数据同步):Eureka 集群中的数据复制与同步。
- Make Remote Call(远程调用):完成服务的远程调用。
5.4 Eureka 自我保护
5.4.1 启动自我保护条件
一般情况下,服务在 Eureka 上注册后,会每 30 秒发送心跳包,Eureka 通过心跳来判断服务是否健康,同时会定期删除超过 90 秒没有发送心跳的服务。
有两种情况会导致 Eureka Server 收不到微服务的心跳
- 微服务自身的原因
- 微服务与 Eureka 之间的网络故障
5.4.2 自我保护模式
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%, Eureka Server 会将这些实例保护起来,让这些实例不会过期,同时提示一个警告。这种算法叫做 Eureka Server 的自我保护模式。
5.5 为什么要启动自我保护
- 因为同时保留"好数据"与"坏数据"总比丢掉任何数据要更好,当网络故障恢复后,这个 Eureka 节点会退出"自我保护模式"。
- Eureka 还有客户端缓存功能(也就是微服务的缓存功能)。即使 Eureka 集群中所有节点都宕机失效,微服务的 Provider 和 Consumer 都能正常通信。
- 微服务的负载均衡策略会自动剔除死亡的微服务节点。
5.6 如何关闭自我保护
注册中心配置自我保护
eureka:
server:
enable-self-preservation: false # true:开启自我保护模式,false:关闭自我保护模式
eviction-interval-timer-in-ms: 60000 # 清理间隔(单位:毫秒,默认是 60*1000)
5.7 Eureka 优雅停服
配置了优雅停服以后,将不需要 Eureka Server 中配置关闭自我保护。本文使用 actuator 实现。
5.7.1 添加依赖
服务提供者添加 actuator 依赖
<!-- spring boot actuator 依赖 -->
<dependency>
<groupId>org.springframework.boot </groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
5.7.2 配置文件
服务提供者配置度量指标监控与健康检查
# 度量指标监控与健康检查
management:
endpoints:
web:
exposure:
include: shutdown # 开启 shutdown 端点访问
endpoint:
shutdown:
enabled: true # 开启 shutdown 实现优雅停服
5.7.3 优雅停服
使用 POST 请求访问:(示例)http://localhost:7070/actuator/shutdown
5.8 Eureka 安全认证
5.8.1 添加依赖
注册中心添加 security 依赖
<!-- spring boot security 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
5.8.2 配置文件
注册中心配置安全认证
spring:
# 安全认证
security:
user:
name: root
password: 123456
5.8.3 修改访问集群节点的 url
注册中心的配置文件
# 配置 Eureka Server 注册中心
eureka:
instance:
hostname: eureka01 # 主机名,不配置的时候将根据操作系统的主机名来获取
prefer-ip-address: true # 是否使用 ip 地址注册
instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
client: # 设置服务注册中心地址,指向另一个注册中心
service-url: # 注册中心对外暴露的注册地址
defaultZone: http://root:123456@localhost:8762/eureka/
服务提供者的配置文件
# 配置 Eureka Server 注册中心
eureka:
instance:
prefer-ip-address: true # 是否使用 ip 地址注册
instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
client:
service-url: # 设置服务注册中心地址
defaultZone: http://root:123456@localhost:8761/eureka/,http://root:123456@localhost:8762/eureka/
服务消费者的配置文件
# 配置 Eureka Server 注册中心
eureka:
client:
register-with-eureka: false # 是否将自己注册到注册中心,默认为 true
registry-fetch-interval-seconds: 10 # 表示 Eureka Client 间隔多久去服务器拉取注册信息, 默认为 30 秒
service-url: # 设置服务注册中心地址
defaultZone: http://root:123456@localhost:8761/eureka/,http://root:123456@localhost:8762/eureka/
5.8.4 过滤 CSRF
Eureka 会自动化配置 CSRF 防御机制,Spring Security 认为 POST, PUT, and DELETE http methods 都是有风险的,如果这些 method 发送过程中没有带上 CSRF token 的话,会被直接拦截并返回 403 forbidden。
解决
首先注册中心配置一个 @EnableWebSecurity 配置类,
继承org.springframework.security.config.annotation.web.configuration.WebSecurityConfi gurerAdapter ,
然后重写 configure 方法。
方案一
使 CSRF 忽略 /eureka/** 的所有请求
package com.xxxx.config;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurer Adapter;
/*** 安全认证配置类 */
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http); // 加这句是为了访问 eureka 控制台和 /actuator 时能做安全控制
http.csrf().ignoringAntMatchers("/eureka/**"); // 忽略 /eureka/** 的所有请求
}
}
方案二
保持密码验证的同时禁用 CSRF 防御机制
package com.xxxx.config;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurer Adapter;
/*** 安全认证配置类 */
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 注意,如果直接 disable 的话会把安全验证也禁用掉
http.csrf().disable().authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic();
}
}