在微服务架构中,一个系统往往由十几甚至几十个服务组成,若将这些服务全部注册到同一个 Eureka Server 中,就极有可能导致 Eureka Server 因不堪重负而崩溃,最终导致整个系统瘫痪。解决这个问题最直接的办法就是部署 Eureka Server 集群。

在 Eureka 实现服务注册与发现时一共涉及了 3 个角色:服务注册中心、服务提供者以及服务消费者,这三个角色分工明确,各司其职。但是其实在 Eureka 中,所有服务都既是服务消费者也是服务提供者,服务注册中心 Eureka Server 也不例外。

我们在搭建服务注册中心时,在 application.yml 中涉及了这样的配置:

eureka:

client:

register-with-eureka: false #false 表示不向注册中心注册自己。

fetch-registry: false #false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务

这样设置的原因是 micro-service-cloud-eureka-7001 本身自己就是服务注册中心,服务注册中心是不能将自己注册到自己身上的,但服务注册中心是可以将自己作为服务向其他的服务注册中心注册自己的。

举个例子,有两个 Eureka Server 分别为 A 和 B,虽然 A 不能将自己注册到 A 上,B 也不能将自己注册到 B 上,但 A 是可以作为一个服务把自己注册到 B 上的,同理 B 也可以将自己注册到 A 上。

这样就可以形成一组互相注册的 Eureka Server 集群,当服务提供者发送注册请求到 Eureka Server 时,Eureka Server 会将请求转发给集群中所有与之相连的 Eureka Server 上,以实现 Eureka Server 之间的服务同步。

通过服务同步,服务消费者可以在集群中的任意一台 Eureka Server 上获取服务提供者提供的服务。这样,即使集群中的某个服务注册中心发生故障,服务消费者仍然可以从集群中的其他 Eureka Server 中获取服务信息并调用,而不会导致系统的整体瘫痪,这就是 Eureka Server 集群的高可用性。

个人理解:

接上章:房东-中介-客户的示例。

中介可不可以做连锁店呢?如果这一个店因为某些不可抗力因素而无法使用,那么我们是否可以换一个连锁店呢?

示例 2

下面我们在示例 1 的基础上进行扩展,构建一个拥有 3 个 Eureka Server 实例的集群。

1. 参照 micro-service-cloud-eureka-7001 的搭建过程,在主工程下另外再创建两个 Eureka Server:micro-service-cloud-eureka-7002 和 micro-service-cloud-eureka-7003,此时这 3 个 Eureka Server 无论是 Maven 依赖、代码还是配置都是一模一样的。

2. 修改 micro-service-cloud-eureka-7001、micro-service-cloud-eureka-7002、micro-service-cloud-eureka-7003 中 application.yml 的配置,具体配置如下 。

micro-service-cloud-eureka-7001 中 application.yml 的配置如下。

server:

port: 7001 #端口号

eureka:

instance:

hostname: eureka7001.com #eureka服务端的实例名称

client:

register-with-eureka: false #false 表示不向注册中心注册自己。

fetch-registry: false #false 表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务

service-url:

#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机版

defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #集群版 将当前的 Eureka Server 注册到 7003 和 7003 上,形成一组互相注册的 Eureka Server 集群

micro-service-cloud-eureka-7002 中 application.yml 的配置如下。

server:

port: 7002 #端口号

eureka:

instance:

hostname: eureka7002.com #Eureka Server 实例名称

client:

register-with-eureka: false #false 表示不向注册中心注册自己。

fetch-registry: false #false 表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务

service-url:

defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/ #将这个 Eureka Server 注册到 7001 和 7003 上

micro-service-cloud-eureka-7003 中 application.yml 的配置如下。

server:

port: 7003 #该 Module 的端口号

eureka:

instance:

hostname: eureka7003.com #eureka服务端的实例名称,

client:

register-with-eureka: false #false表示不向注册中心注册自己。

fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务

service-url:

#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机版服务注册中心

defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #集群版 将当前的 Eureka Server 注册到 7003 和 7003 上,形成一组互相注册的 Eureka Server 集群

3. 由于我们是在本地搭建的 Eureka Server 集群,因此我们需要修改本地的 host 文件,【配置伪域名】

Windows 操作系统的电脑在 C:\Windows\System32\drivers\etc/hosts 中修改,

Mac 系统的电脑则需要在 vim/etc/hosts 中修改,修改内容如下。

#Spring Cloud eureka 集群

127.0.0.1 eureka7001.com

127.0.0.1 eureka7002.com

127.0.0.1 eureka7003.com

 

测试伪域名配置情况

4. 修改 micro-service-cloud-provider-emp-8001(服务提供者)配置文件 application.yml 中 eureka.client.service-url.defaultZone 的取值,将服务注册到 Eureka Server 集群上,具体配置如下。

eureka:

client: #将客户端注册到 eureka 服务列表内

service-url:

#defaultZone: http://localhost:7001/eureka #这个地址是 7001注册中心在 application.yml 中暴露出来额注册地址 (单机版)

defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #将服务注册到 Eureka Server 集群

5. 启动 micro-service-cloud-eureka-7001,使用浏览器访问“http://eureka7001.com:7001/”,结果如下图。

图5:Eureka Server 集群 -7001

从上图可以看到, 服务提供者(micro-service-cloud-provider-emp-8001)的服务已经注册到了 Eureka Server 7001,并且在 DS Replicas 选项中也显示了集群中的另外两个 Eureka Server:Eureka Server 7002 和 Eureka Server 7003。

6. 启动 micro-service-cloud-eureka-7002,使用浏览器访问“http://eureka7002.com:7002/”,结果如下图。

图6:Eureka Server 集群 -7002

从上图可以看到, 服务提供者(micro-service-cloud-provider-emp-8001)所提供的服务已经注册到了 Eureka Server 7002,并且在 DS Replicas 选项中也显示了集群中的另外两个 Eureka Server:Eureka Server 7001 和 Eureka Server 7003。

7. 启动 micro-service-cloud-eureka-7003,使用浏览器访问“http://eureka7003.com:7003/”,结果如下图。

图7:Eureka Server 集群 -7003

从上图可以看到, 服务提供者(micro-service-cloud-provider-emp-8001)所提供的服务已经注册到了 Eureka Server 7003,并且在 DS Replicas 选项中也显示了集群中的另外两个 Eureka Server:Eureka Server 7001 和 Eureka Server 7002。

自此我们就完成了 Eureka Server 集群的搭建和使用。

Eureka 自我保护机制

我们在本地调试基于 Eureka 的程序时,Eureka 服务注册中心很有可能会出现如下图所示的红色警告。

图8: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 自我保护机制触发期间,服务提供者提供的服务出现问题,那么服务消费者就很容易获取到已经不存在的服务进而出现调用失败的情况,此时,我们可以通过客户端的容错机制来解决此问题,[后续章节讲解]

默认情况下,Eureka 的自我保护机制是开启的,如果想要关闭,则需要在配置文件中添加以下配置。

eureka:

server:

enable-self-preservation: false # false 关闭 Eureka 的自我保护机制,默认是开启,一般不建议大家修改

示例 3

下面我们通过一个实例,来验证下 Eureka 的自我保护机制。

1. 在 micro-service-cloud-eureka-7001 的配置文件 application.yml 中添加以下配置,关闭 Eureka 的自我保护机制。

server:

port: 7001 #该 Module 的端口号

eureka:

server:

enable-self-preservation: false #false 关闭 Eureka 的自我保护机制,默认是开启,一般不建议大家修改

instance:

hostname: eureka7001.com #eureka服务端的实例名称,

client:

register-with-eureka: false #false表示不向注册中心注册自己。

fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务

service-url:

#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机版服务注册中心

defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #集群版 将当前的 Eureka Server 注册到 7003 和 7003 上,形成一组互相注册的 Eureka Server 集群

2. 集群中的 micro-service-cloud-eureka-7002 和 micro-service-cloud-eureka-7002 不作任何修改,即它们的自我保护机制是开启的。

3. 重启 Eureka Server 集群以及 micro-service-cloud-provider-emp-8001,使用浏览器访问“http://eureka7001.com:7001/”,结果如下图。

Eureka 关闭自我保护机制

在 DS Replicas 选项上面出现了红色警告信息“THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.”,出现该信息则表示“ Eureka 自我保护模式已关闭。” micro-service-cloud-provider-emp-8001 提供的服务已经注册到该 Eureka Server 中

4. 使用浏览器访问“http://eureka7002.com:7002/”,结果如下图

Eureka 自我保护机制

micro-service-cloud-provider-emp-8001 提供的服务也已经注册到当前 Eureka Server 中,但 DS Replicas 选项上方没有任何警告提示。

5. 关闭 micro-service-cloud-provider-emp-8001,等待几分钟,再次访问“http://eureka7001.com:7001/”,结果如下图。

Eureka 关闭自我保护机制-2

在 DS Replicas 选项上面出现了红色警告信息“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.”,出现该信息则表示 Eureka 的自我保护模式已关闭,且已经有服务被移除。micro-service-cloud-provider-emp-8001 提供的服务已经从服务列表中移除。

6.再次访问“http://eureka7002.com:7002/”,结果如下图。

Eureka 自我保护机制生效

在 DS Replicas 选项上面出现了红色警告信息“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 的自我保护机制处于开启状态,且已经被触发。micro-service-cloud-provider-emp-8001 的服务信息依然保存 Eureka Server 服务注册表中,并未被移除。

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。

大家都在找:

eureka:eureka的寓意

java:java官网64位

云原生:云原生容器

大家都在看: