eureka底层原理

Posted java叶新东老师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了eureka底层原理相关的知识,希望对你有一定的参考价值。

什么是注册中心

全称为:服务注册与发现,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 缓存中去。如图

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

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获取到具体的注册列表;

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服务器发送取消请求。 发送请求后,该客户端实例信息将从服务器的实例注册表中删除。该下线请求不会自动完成,它需要调用以下内容:

  DiscoveryManager.getInstance().shutdownComponent()

7、Eviction 服务剔除

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

以上是关于eureka底层原理的主要内容,如果未能解决你的问题,请参考以下文章

eureka底层原理

SpringCloud系列四:Eureka 服务发现框架(定义 Eureka 服务端Eureka 服务信息Eureka 发现管理Eureka 安全配置Eureka-HA(高可用) 机制Eur(代码片段

Spring Cloud底层原理

js根据类名获取元素的底层原理

Spring Cloud Netflix-Eureka集群数据同步

面试官:说说Spring Cloud底层原理?