文章目录
1 Eureka
1.1 什么是Eureka注册中心
Eureka
是Netflix
开发的服务发现组件, 本身是一个基于 REST
的服务。
Spring Cloud
将它集成在其子项目 spring-cloud-netflix
中, 以实现 Spring Cloud
的服务注册于发现
, 同时还提供了负载均衡
、 故障转移
等能力。
1.2 Eureka注册中心三种角色
1.2.1 Eureka Server
通过 Register、 Get、 Renew
等接口提供服务的注册和发现。
1.2.2 Application Service (Service Provider)
服务提供方
:把自身的服务实例注册到 Eureka Server
中
1.2.3 Application Client (Service Consumer)
服务调用方
:通过 Eureka Server
获取服务列表, 消费服务
1.3 原理图
Register(服务注册)
: 把自己的 IP
和端口注册给 Eureka
。
Renew(服务续约)
: 发送心跳包, 每 30
秒发送一次。 告诉 Eureka
自己还活着。
Cancel(服务下线)
: 当 provider
关闭时会向 Eureka
发送消息, 把自己从服务列表中删除。 防止 consumer
调用到不存在的服务。
Get Registry(获取服务注册列表)
: 获取其他服务列表。
Replicate(集群中数据同步)
: eureka
集群中的数据复制与同步。
Make Remote Call(远程调用)
: 完成服务的远程调用。
2 CAP
2.1 什么是CAP原则
CAP
原则又称CAP
定理, 指的是在一个分布式系统
中, Consistency
(一致性) 、Availability
(可用性) 、 Partition tolerance
(分区容错性) , 三者不可兼得。
原则分类 | 详解 |
---|---|
C 数据一致性( Consistency ) |
也叫做数据原子性系统在执行某项操作后仍然处于一致的状态。 在分布式系统中, 更新操作执行成功后所有的用户都应该读到最新的值,这样的系统被认为是具有强一致性 的。 等同于所有节点访问同一份最新的数据副本 |
A 服务可用性( Availablity ) |
每一个操作总是能够在一定的时间内返回结果, 这里需要注意的是一定时间内 和返回结果 。 一定时间内指的是,在可以容忍的范围内返回结果, 结果可以是成功或者是失败 |
P 分区容错性( Partition-torlerance ) |
在网络分区的情况下, 被分隔的节点仍能正常对外提供服务(分布式集群, 数据被分布存储在不同的服务器上, 无论什么情况, 服务器都能正常被访问) |
2.2 如何舍弃
定律
: 任何分布式系统只可同时满足二点,没法三者兼顾
三者择其二 | 分析 |
---|---|
CA, 放弃 P |
如果想避免分区容错性问题的发生, 一种做法是将所有的数据(与事务相关的)都放在一台机器上。 虽然无法 100%保证系统不会出错, 单不会碰到由分区带来的负面效果。 当然这个选择会严重的影响系统的扩展性 |
CP, 放弃 A |
相对于放弃"分区容错性"来说, 其反面就是放弃可用性。一旦遇到分区容错故障, 那么受到影响的服务需要等待一定时间, 因此在等待时间内系统无法对外提供服务 |
AP, 放弃 C |
这里所说的放弃一致性, 并不是完全放弃数据一致性,而是放弃数据的强一致性, 而保留数据的最终一致性。 以网络购物为例, 对只剩下一件库存的商品, 如果同时接受了两个订单, 那么较晚的订单将被告知商品告罄 |
2.3 eureka与zookeeper区别
对比项 | Zookeeper | Eureka | |
---|---|---|---|
CAP | CP | AP | |
Dubbo 集成 | 已支持 | - | |
Spring Cloud 集成 | 已支持 | 已支持 | |
kv 服务 | 支持 | - | ZK 支持数据存储,eureka不支持 |
使用接口(多语言能力) | 提供客户端 | http 多语言 | ZK的跨语言支持比较弱 |
watch 支持 | 支持 | 支持 | 什么是Watch 支持?就是客户单监听服务端的变化情况。zk 通过订阅监听来实现eureka 通过轮询的方式来实现 |
集群监控 | - | metrics | metrics,运维者可以收集并报警这些度量信息达到监控目的 |
3 eureka优雅停服
3.1 Eureka自我保护
3.1.1 自我保护的条件
一般情况下, 微服务在Eureka
上注册后, 会每30
秒发送心跳包,Eureka
通过心跳来判断服务是否健康, 同时会定期删除超过90
秒没有发送心跳服务。
3.1.2 Eureka Server收不到微服务的心跳
- 是微服务自身的原因
- 是微服务与
Eureka
之间的网络故障,通常(微服务的自身的故障关闭)只会导致个别服务出现故障, 一般不会出现大面积故障, 而(网络故障)通常会导致Eureka Server
在短时间内无法收到大批心跳。
考虑到这个区别,Eureka
设置了一个阀值
, 当判断挂掉的服务的数量超过阀值时,Eureka Server
认为很大程度上出现了网络故障, 将不再删除心跳过期的服务。
3.1.3 eureka阀值
15
分钟之内是否低于85%
;Eureka Server
在运行期间,会统计心跳失败的比例在15
分钟内是否低于85%
这种算法叫做Eureka Server
的自我保护模式
3.2 为什么需要eureka自我保护
- 因为同时保留
好数据
与坏数据
总比丢掉任何数据要更好, 当网络故障恢复后,这个Eureka
节点会退出自我保护模式
。 Eureka
还有客户端缓存功能(也就是微服务的缓存功能)。 即便Eureka
集群中所有节点都宕机失效, 微服务的Provider
和Consumer
都能正常通信。- 微服务的
负载均衡
策略会自动剔除死亡的微服务节点
3.3 关闭自我保护
修改 Eureka Server
配置文件
#关闭自我保护:true 为开启自我保护, false 为关闭自我保护
eureka.server.enableSelfPreservation=false
#清理间隔(从服务列表删除无用服务的时间间隔,单位:毫秒, 默认是 60*1000)
eureka.server.eviction.interval-timer-in-ms=60000
3.4 优雅停服
环境:springboot:2.1.3 springcloud:Greenwich.SR5
3.4.1 不需要在Eureka Server中配置关闭自我保护
3.4.2 添加actator的坐标依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3.4.3 修改properties文件
###### 优雅停服######
##启用 shutdown
management.endpoint.shutdown.enabled=true
# 暴露所有端点
management.endpoints.web.exposure.include=*
#禁用密码验证
management.endpoints.shutdown.sensitive=false
3.4.4 发送关闭服务的URL请求
post
请求
public static String doPost(String url,Map<String,String> param) {
//创建HTTPClient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
try{
//创建httpget请求
HttpPost httpPost = new HttpPost(url);
if(MapUtils.isNotEmpty(param)) {
List<NameValuePair> paramList= new ArrayList<>();
param.forEach((a,b)->paramList.add(new BasicNameValuePair(a,b)));
//模拟表单
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(paramList,"utf-8");
//UrlEncodedFormEntity 来设置 body,消息体内容类似于“KEY1=VALUE1&KEY2=VALUE2&...
httpPost.setEntity(formEntity);
}
//执行请求
response = httpClient.execute(httpPost);
if(response.getStatusLine().getStatusCode()==200) {
System.out.println("========成功========");
resultString = EntityUtils.toString(response.getEntity(),"utf-8");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(response!=null)response.close();
httpClient.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return resultString;
}
main
方法发送
public static void main(String[] args) throws Exception {
String url ="http://127.0.0.1:9080/actuator/shutdown";
//该 url 必须要使用 dopost 方式来发送
HttpClientUtil.doPost(url,null);
}
在main
方法发送后,就可以在本地看到启动的服务自己就关闭了,也可以在服务注册管理页面查看
4 eureka的安全认证
4.1 在Eureka Server中添加 security 包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
4.2 修改Eureka Server配置文件
#开启 http basic 的安全认证 没有用 需要通过下面方法来关闭或开启
#spring.security.basic.enabled=true
spring.security.user.name=user
spring.security.user.password=123456
# 修改访问集群节点的 url
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka2:8761/eureka/
4.3 修改微服务的配置文件添加访问注册中心的用户名与密码
spring.application.name=eureka-provider
server.port=9090
#设置服务注册中心地址, 指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
#启用 shutdown
management.endpoints.shutdown.enabled=true
#禁用密码验证
management.endpoints.shutdown.sensitive=false
4.4 关闭csrf认证
Spring Cloud 2.0
以上的security
默认启用了csrf
检验,要在eurekaServer
端配置security
的csrf
检验为false
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); //关闭csrf
//开启认证 若注释掉,就关闭认证了
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}