eureka底层原理「建议收藏」

2022-11-10 16:38:59 浏览数 (2)

什么是注册中心

全称为:服务注册与发现,rpc远程调用框架核心思想,在于注册中心,使用注册中心管理每个服务与服务之间的依赖关系,这种关系被称为服务治理概念;任何rpc远程调用框架都至少有一个注册中心;

服务注册 将服务信息注册到注册中心,相当于告诉公司的人, 我已经打卡上班了,可以分配工作任务给我了,比如现在我们有一个服务消费者 服务A,和两个节点的服务提供者,服务B。服务A 和服务B 在启动的时候都会向注册中心进行服务注册。

服务发现 从注册中心获取已注册的服务信息,发现有哪些可以调用的服务可供我使用;相当于老板知道了哪些人已经上班;

注册中心的作用

存放微服务的地址和相关信息(接口地址), 当一个服务注册到注册中心之后,这个服务既可以作为提供者,也可以作为消费者;可以调别的服务,也可以被别的服务调用;

eureka原理

1.、client端注册

Eureka client启动的时候将自己的IP端口服务名称等信息注册到eureka server

2、心跳与故障检测

服务注册中心还有一个很重要的功能就是 心跳与故障检查。心跳跟故障检测其实就是为了知道注册上来的这些服务是不是还活着的。EurekaClient作为java客户端,在服务启动后周期性的(默认30s)向EurekaServer发送心跳包,若在一定时间内未收到心跳包,则会从服务注册表移除该实例。

发送心跳包也被称为续约。 通过续约来告知Eureka Server该Eureka客户仍然存在,没有出现问题。 正常情况下,如果Eureka Server在90秒没有收到Eureka客户的续约,它会将实例从其注册表中删除。 建议不要更改续约间隔。

当出现机器故障没有在约定的时间(90秒)间隔内上报自己的状态,那么Eureka 就会把这台机器剔除注册表,同时更新到 ReadWrite 缓存中去。如图

自行设置心跳时间 和 超时移除服务时间

代码语言:javascript复制
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka/,http://localhost:8000/eureka/  #多个eurekaserver之间通过","分割
  instance:
    prefer-ip-address: true #使用IP地址注册
    instance-id: ${ 
   spring.cloud.client.ip-address}:${ 
   server.port}   #向注册中心注册我们的IP和端口
    lease-renewal-interval-in-seconds: 5    #设置向注册中心发送心跳的时间,默认是30秒
    lease-expiration-duration-in-seconds: 10  #设置预约到期时间默认是90秒

3、EurekaClient会缓存注册表信息

Eureka客户端从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。每次返回注册列表信息可能与Eureka客户端的缓存信息不同, Eureka客户端自动处理。

如果由于某种原因导致注册列表信息不能及时匹配,Eureka客户端则会重新获取整个注册表信息。 Eureka服务器缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka客户端和Eureka 服务器可以使用JSON / XML格式进行通讯。在默认的情况下Eureka客户端使用压缩JSON格式来获取注册列表的信息。

当Eureka客户端向Eureka Server注册时,它提供自身的元数据,比如IP地址、端口,运行状况指示符URL,主页等。

当client缓存在本地的注册表信息,代码层面可通过DiscoveryClient获取到具体的注册列表;

代码语言:javascript复制
package com.web.controller;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/** * RestTemplate 远程调用示例 */
@RestController
public class RestTemplateController { 

// 可获取注册服务表
@Resource
private DiscoveryClient discoveryClient;
@RequestMapping("/getBizInfo")
public String getBizInfo(){ 

// 获取service-user的所有服务列表
List<ServiceInstance> instances = discoveryClient.getInstances("service-user");
for (ServiceInstance instance : instances) { 

System.out.println(instance.getUri().toString());
}
return "";
}
}

4、EurekaServer之间会相互复制注册表信息

Eureka server端提供服务注册,服务信息提供,服务管理(通过Eureka Client的Cancel、心跳监控、renew等方式来维护该服务提供的信息以确保该服务可用以及服务的更新

在eureka server端集群环境下,各个服务端的注册表信息会互相复制,从而确保节点中数据一致。但在页面上看,只有主服务能看到全部服务连接信息,从服务只能看到主服务的连接信息;

每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过P2P复制的方式完成服务注册表的同步。同步时,被同步信息不会同步出去。也就是说有3个Eureka Server,Server1有新的服务信息时,同步到Server2后,Server2和Server3同步时,Server2不会把从Server1那里同步到的信息同步给Server3,只能由Server1自己同步给Server3。

5、一级缓存和二级缓存

当服务在拉取服务注册表的时候,其实客户端不是直接从 Eureka 中的 服务注册表中获取数据的。Eureka 做了二级缓存,第一级叫做 ReadOnly 缓存,二级叫做 ReadWrite 缓存。

客户端会直接从ReadOnly 缓存中读取注册表信息。当服务在进行注册的时候,先往服务注册表中写入注册信息,服务注册表更新了,立马会同步一份数据到 ReadWrite 缓存中去。

那什么时候 ReadWrite 缓存中的数据会到 ReadOnly 缓存中去?

此时有一个定时任务会定时去检查 ReadWrite 是否跟 ReadOnly 不一致,不一致就把数据同步到 ReadOnly 中去。这个定时任务也默认是 30S。也可以自己配置。

二级缓存的好处在于,优化并发读写的冲突。

如果服务进行注册的时候,同时有服务来读去注册表信息,就会存在频繁的读写加锁的操作,写的时候就不能读,导致性能下降,所以我们需要避免大量的读写都去操作一个表。

那么有了这两层,其实大部分的读操作都会走 ReadOnly 缓存。只需要定时把 ReadWrite 缓存中的数据写入到 ReadOnly 就好了。

6、Cancel:服务下线

Eureka客户端在程序关闭时向Eureka服务器发送取消请求。 发送请求后,该客户端实例信息将从服务器的实例注册表中删除。该下线请求不会自动完成,它需要调用以下内容:

代码语言:javascript复制
  DiscoveryManager.getInstance().shutdownComponent();

7、Eviction 服务剔除

在默认的情况下,当Eureka客户端连续90秒没有向Eureka服务器发送服务续约,即心跳,Eureka服务器会将该服务实例从服务注册列表删除,即服务剔除。

8、自我保护机制

Eureka Server 在检测到心跳异常后会将服务实例保护起来,让这些实例不会马上过期,自我保护机制的工作机制是如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制,此时会出现以下几种情况:

  1. Eureka Server不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。
  2. Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用。
  3. 当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。

但是在保护期内如果服务刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,此时会调用失败,对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。

我们在单机测试的时候很容易满足心跳失败比例在 15 分钟之内低于 85%,这个时候就会触发 Eureka 的保护机制,一旦开启了保护机制,则服务注册中心维护的服务实例就不是那么准确了,此时我们可以关闭保护机制,这样可以确保注册中心中不可用的实例被及时的剔除(不推荐)。

代码语言:javascript复制
#properties配置方式
# 自我保护机制,默认开启
eureka.server.enable-self-preservation=true
# yml配置方式
eureka:
server:
# 自我保护机制,默认开启
enable-self-preservation: true

关闭自我保护机制后在eureka页面会显示一排红字THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.,意思是说 :自我保护模式已关闭。如果出现网络/其他问题,这可能无法保护实例过期。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/184763.html原文链接:https://javaforall.cn

0 人点赞