04.SpringCloud - Spring Cloud Netflix 之 Eureka 集群,Ribbon(四)
04.SpringCloud - Spring Cloud Netflix 之 Eureka 集群,Ribbon(四)
阅读本文前可先参考
SpringCloud - Spring Cloud根/父项目,开发准备(二)_MinggeQingchun的博客-CSDN博客
一、Eureka 与 Zookeeper 的比较
分布式系统的最大难点,就是各个节点的状态如何保持一致。CAP理论是在设计分布式系统的过程中,处理数据一致性问题时必须考虑的理论
CAP理论,指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性),不能同时成立
Consistency一致性( 数据**):**对于客户端的每次读操作,要么读到的是最新的数据,要么读取失败。换句话说,一致性是站在分布式系统的角度,对访问本系统的客户端的一种承诺:要么我给您返回一个错误,要么我给你返回绝对一致的最新数据,不难看出,其强调的是数据正确。
Availability**可用性(服务):**任何客户端的请求都能得到响应数据,不会出现响应错误。换句话说,可用性是站在分布式系统的角度,对访问本系统的客户的另一种承诺:我一定会给您返回数据,不会给你返回错误,但不保证数据最新,强调的是不出错。
Partition Tolerance**分区容忍性(服务OK,网络间断):**由于分布式系统通过网络进行通信,网络是不可靠的。当任意数量的消息丢失或延迟到达时,系统仍会继续提供服务,不会挂掉。换句话说,分区容忍性是站在分布式系统的角度,对访问本系统的客户端的再一种承诺:我会一直运行,不管我的内部出现何种数据同步问题,强调的是不挂掉。
分区容错性在是分布式系统中必须要保证的,因此只能在 A 和 C 之间进行权衡
Zookeeper 保证的是 CP, 而 Eureka 则是 AP
Zookeeper 保证 CP
在 ZooKeeper 中,当 master 节点因为网络故障与其他节点失去联系时,剩余节点会重新进行 leader 选举,但是问题在于,选举 leader 需要一定时间, 且选举期间整个 ZooKeeper 集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得 ZooKeeper 集群失去 master 节点是大概率事件,虽然服务最终能够恢复,但是在选举时间内导致服务注册长期不可用是难以容忍的。
Eureka 保证 AP
Eureka 优先保证可用性,Eureka 各个节点是平等的,某几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而 Eureka 的客户端在向某个 Eureka 注册时如果发现连接失败,则会自动切换至其它节点,只要有一台 Eureka 还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。
所以 Eureka 在网络故障导致部分节点失去联系的情况下,只要有一个节点可用, 那么注册和查询服务就可以正常使用,而不会像 zookeeper 那样使整个注册服务瘫痪,Eureka 优先保证了可用性
二、Eureka集群部署
在微服务架构的这种分布式系统中,我们要充分考虑各个微服务组件的高可用性
由于注册中心 eureka 本身也是一个服务,如果它只有一个节点,那么它有可能发生故障,这样我们就不能注册与查询服务了,所以需要一个高可用的服务注册中心,这就需要通过注册中心集群来解决。
eureka 服务注册中心它本身也是一个服务,它也可以看做是一个提供者,又可以看做是一个消费者,我们之前通过配置:
eureka.client.register-with-eureka=false
让注册中心不注册自己,但是我们可以向其他注册中心注册自己;Eureka Server 的高可用实际上就是将自己作为服务向其他服务注册中心注册自己,这样就会形成一组互相注册的服务注册中心,进而实现服务清单的互相同步,往注册中心 A 上注册的服务,可以被复制同步到注册中心 B 上,所以从任何一台注册中心上都能查询到已经注册的服务,从而达到高可用的效果
1、在 springcloud-3-service-eureka 模块中复制 3 份 application.properties 配置文件
application-eureka8761.properties
application-eureka8762.properties
application-eureka8763.properties
2、分别修改各自端口号 8761,8762,8763
3、指定服务注册中心的位置
在 8761 的配置文件中,让它的 service-url 指向 8762和8763,在 8762 的配置文件中让它的 service-url 指向 8761和8763, 在 8763 的配置文件中让它的 service-url 指向 8761和8762;
#内嵌Tomcat端口
server.port=8761
#指定服务注册中心的位置
eureka.client.service-url.defaultZone=http://eureka8762:8762/eureka,http://eureka8763:8763/eureka
#内嵌Tomcat端口
server.port=8762
#指定服务注册中心的位置
eureka.client.service-url.defaultZone=http://eureka8761:8761/eureka,http://eureka8763:8763/eureka
#内嵌Tomcat端口
server.port=8763
#指定服务注册中心的位置
eureka.client.service-url.defaultZone=http://eureka8761:8761/eureka,http://eureka8762:8762/eureka
两两互相指向对方,实际上我们构建了一个三节点的服务注册中心集群
4、修改本地 hosts 文件配置:C:\Windows\System32\drivers\etc\hosts
127.0.0.1 eureka8761
127.0.0.1 eureka8762
127.0.0.1 eureka8763
5、 选择 Edit Configurations
选中Eureka server 项目 ,复制3 份,并分别改名;在运行配置项目 Program Arguments 中配置启动文件
6、分别启动 3个 eureka server,在eureka 控制台查看状态
浏览器分别输入 http://localhost:8761/;http://localhost:8762/;http://localhost:8763/
1、我们将Eureka 打成 jar包 发布到Linux 服务器上
在远程服务器上创建一个文件夹
编写脚本eureka.sh ,创建 logs 文件夹
启动时对于properties文件,不同的环境激活不同的配置文件
#!/bin/sh
nohup java -jar springcloud-3-service-eureka.jar --spring.profiles.active=eureka8761 > ./logs/eureka8761.log &
nohup java -jar springcloud-3-service-eureka.jar --spring.profiles.active=eureka8762 > ./logs/eureka8762.log &
nohup java -jar springcloud-3-service-eureka.jar --spring.profiles.active=eureka8763 > ./logs/eureka8763.log &
运行脚本 ,并查看Java进程
sh eureka.sh
查看Java进程
ps -ef |grep java
2、 修改Linux的hosts文件
vim /etc/hosts
192.168.12.128 eureka8761
192.168.12.128 eureka8762
192.168.12.128 eureka8763
重启
/etc/init.d/network restart # 重启网络
/etc/init.d/net.eth0 restart # 这个就是重启网卡了
临时关闭 Linux上的防火墙
systemctl status firewalld
systemctl stop firewalld
浏览器输入查看
三、Eureka服务注册中心自我保护机制
当我们在本地调试基于 Eureka 的程序时,Eureka 服务注册中心很有可能会出现如下图所示的红色警告
红字提醒警告主要有如下:
THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
自我保护机制被关闭,这将导致在网络或者其他异常发生的情况下不会保护过期的实例
RENEWALS ARE LESSER THAN THE THRESHOLD. THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
续约阀值过低,自我保护机制被关闭,这将导致在网络或者其他异常发生的情况下不会保护过期的实例
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.
紧急!因续约阀值过低,Eureka自我保护机制已启动,为安全起见,可能导致一些本已过期的实例不会被剔除注册中心
实际上,这个警告是触发了 Eureka 的自我保护机制而出现的。默认情况下,如果 Eureka Server 在一段时间内(默认为 90 秒)没有接收到某个服务提供者(Eureka Client)的心跳,就会将这个服务提供者提供的服务从服务注册表中移除。 这样服务消费者就再也无法从服务注册中心中获取到这个服务了,更无法调用该服务。
但在实际的分布式微服务系统中,健康的服务(Eureka Client)也有可能会由于网络故障(例如网络延迟、卡顿、拥挤等原因)而无法与 Eureka Server 正常通讯。若此时 Eureka Server 因为没有接收心跳而误将健康的服务从服务列表中移除,这显然是不合理的。而 Eureka 的自我保护机制就是来解决此问题的。
所谓 "Eureka 的自我保护机制",其中心思想就是"好死不如赖活着"。如果 Eureka Server 在一段时间内没有接收到 Eureka Client 的心跳,那么 Eureka Server 就会开启自我保护模式,将所有的 Eureka Client 的注册信息保护起来,而不是直接从服务注册表中移除。一旦网络恢复,这些 Eureka Client 提供的服务还可以继续被服务消费者消费。
综上,Eureka 的自我保护机制是一种应对网络异常的安全保护措施。它的架构哲学是:宁可同时保留所有微服务(健康的服务和不健康的服务都会保留)也不盲目移除任何健康的服务。通过 Eureka 的自我保护机制,可以让 Eureka Server 集群更加的健壮、稳定。
默认情况下,Eureka 的自我保护机制是开启的,如果想要关闭,则需要在配置文件中添加以下配置。
#禁用自我保护模式
eureka.server.enable-self-preservation = false
关于自我保护常用几个配置如下:
服务器端配置:
#测试时关闭自我保护机制,保证不可用服务及时踢出
eureka.server.enable-self-preservation=false
客户配置:
#每间隔 2s,向服务端发送一次心跳,证明自己依然"存活"
eureka.instance.lease-renewal-interval-in-seconds=2
#告诉服务端,如果我 10s 之内没有给你发心跳,就代表我故障了,将我踢出掉
eureka.instance.lease-expiration-duration-in-seconds=10
来源:https://blog.csdn.net/MinggeQingchun/article/details/125277895