Eureka相关问题

一、Eureka介绍

Eureka来源于古希腊词汇,意为“发现了”。词源同 heuristic
据说最早来自古希腊物理学家阿基米德,国王给他一顶金冠让他判断是否纯金,阿基米德苦思不得,一次在泡澡时通过浮力原理找到了方法,因而大喊该词。
“启发式的探索”
Eureka是Netflix 在线影片公司开源的一个服务注册与发现的组件,和其他Netflix公司的服务组件(例如负载均衡、熔断器、网关等)一起,被Spring Cloud 社区整合为Spring Cloud Netflix 模块。
和Consul 、Zookeeper 类似, Eureka是一个用于服务注册和发现的组件。Eureka 分为Eureka Server 和Eureka Client, Eureka Server 为Eureka服务注册中心,Eureka Client为Eureka客户端

Eureka中的一些概念

1)Register:服务注册

当Eureka客户端向Eureka Server注册时,它提供自身的元数据,比如IP地址、端口、运行状态指示符URL,主页等。
2)Renew:服务续约(服务更新)

Eureka客户端会每隔30秒发送一次心跳来续约。通过续约来告知Eureka Server该Eureka客户仍然存在,没有出现问题。
正常情况下,如果Eureka Server在三次心跳间隔期间没有收到心跳包的情况(Eureka Server在90s内没有收到Eureka Client发送的心跳包),它将会把该Eureka客户的实例从其注册表删除。

3)Fetch Registries:获取注册列表信息
·Eureka客户端从服务器获取注册表信息,并将其缓存在本地。
·客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。每次返回注册列表信息可能与Eureka客户端的缓存信息不同, Eureka客户端自动处理。
·如果由于某种原因导致注册列表信息不能及时匹配,Eureka客户端则会重新获取整个注册表信息。
·Eureka服务器缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。
·Eureka客户端和Eureka 服务器可以使用JSON / XML格式进行通讯。在默认的情况下Eureka客户端使用压缩JSON格式来获取注册列表的信息。

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

    DiscoveryManager.getInstance().shutdownComponent();

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

二、Eureka的框架

在这里插入图片描述
1)在体系中,Eureka Client和Eureka Server分别是Eureka的客户端和Eureka的服务端
2)在Eureka的客户端有分为Application Service和Application Client
服务的提供方和服务的消费方。
3)Eureka Client向Eureka Server注册,并将自己的一些客户端信息发送到Eureka Server。
Eureka Client通过每30s发送心跳到Eureka Server来实现续约服务。
4)注册信息和续订信息都被复制到Eureka Server集群中的所有节点。来自任何区域的Eureka Client都可以查找注册信息(30s一次)。根据这些注册表信息,Application Client可以远程调用Application Service 来消费服务。
远程调用可以大致理解为:
Application Client →Eureka Client→ Application Service
而Eureka Server提供给Eureka Client查找注册表信息。

三、配置Eureka

配置Eureka客户端的最简单的方法是使用属性配置文件。
默认情况下,Eureka客户端在classpath中搜索属性文件eureka-client.properties。
它进一步在特定于环境的属性文件中搜索特定于环境的覆盖。环境通常是test或prod,由-Deureka.environment java 命令行开关提供给eureka客户端(没有.properties后缀)。因此,客户端也会搜索eureka-client-{test,prod}.properties。

四、服务注册的跟踪分析

在这里插入图片描述
在Eureka Client启动的时候,将自身的服务的信息发送到Eureka Server。
在com.netflix.discovery包下有个DiscoveryClient类,该类包含了Eureka Client向Eureka Server发送信息的相关方法。
其中DiscoveryClient也实现了EurekaClient接口,并且它是一个单例模式。而EurekaClient继承了LookupService接口
1、在DiscoveryClient类有一个服务注册的方法register(),该方法是通过http请求向Eureka Client 注册。
2、在DiscoveryClient类继续跟踪 register()方法,它被InstanceInfoReplicator 类的run()方法调用,其中InstanceInfoReplicator实现了Runnable接口。
3、InstanceInfoReplicator类是在DiscoveryClient初始化过程中使用的,其中有一个initScheduledTasks()方法。该方法主要开启了获取服务注册列表的信息,如果需要向Eureka Server注册,则开启注册,同时开启了定时向Eureka Server服务续约的定时任务。
4、在来看Eureka server端的代码,在Maven的eureka-core:1.6.2的jar包下。打开com.netflix.eureka包,很轻松的就发现了又一个EurekaBootStrap的类,BootStrapContext具有最先初始化的权限

protected void initEurekaServerContext() throws Exception {

 ...//省略代码
   PeerAwareInstanceRegistry registry;
        if (isAws(applicationInfoManager.getInfo())) {
           ...//省略代码,如果是AWS的代码
        } else {
            registry = new PeerAwareInstanceRegistryImpl(
                    eurekaServerConfig,
                    eurekaClient.getEurekaClientConfig(),
                    serverCodecs,
                    eurekaClient
            );
        }

        PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(
                registry,
                eurekaServerConfig,
                eurekaClient.getEurekaClientConfig(),
                serverCodecs,
                applicationInfoManager
        );
 }

5、其中PeerAwareInstanceRegistryImpl和PeerEurekaNodes两个类看其命名,应该和服务注册以及Eureka Server高可用有关。先追踪PeerAwareInstanceRegistryImpl类,在该类有个register()方法,该方法提供了注册,并且将注册后信息同步到其他的Eureka Server服务。

6、其中 super.register(info, leaseDuration, isReplication)方法,点击进去到子类AbstractInstanceRegistry可以发现更多细节,其中注册列表的信息被保存在一个Map中。replicateToPeers()方法,即同步到其他Eureka Server的其他Peers节点,追踪代码,发现它会遍历循环向所有的Peers节点注册,最终执行类PeerEurekaNodes的register()方法,该方法通过执行一个任务向其他节点同步该注册信息

经过一系列的源码追踪,可以发现PeerAwareInstanceRegistryImpl的register()方法实现了服务的注册,并且向其他Eureka Server的Peer节点同步了该注册信息。
Eureka Client是通过 http来向Eureka Server注册的,那么Eureka Server肯定会提供一个注册的接口给Eureka Client调用,那么PeerAwareInstanceRegistryImpl的register()方法肯定最终会被暴露的Http接口所调用。

五、Eureka Client注册一个实例为什么这么慢?

Eureka Client一启动,不是立即想Eureka Server注册,它会有一个延迟向服务注册的的时间。
查看源码,可以发现默认的延迟时间为40秒
源码在DaufltEurekaClientConfig类下


public int getInitialInstanceInfoReplicationIntervalSeconds() {
    return configInstance.getIntProperty(
        namespace + INITIAL_REGISTRATION_REPLICATION_DELAY_KEY, 40).get();
 }

Eureka Server的响应缓存
Eureka Server维护每30秒更新的响应缓存,可通过更改配置eureka.server.responseCacheUpdateIntervalMs来修改。 所以即使实例刚刚注册,它也不会出现在调用/ eureka / apps REST端点的结果中。
Eureka Server刷新缓存
Eureka客户端保留注册表信息的缓存。 该缓存每30秒更新一次(如前所述)。 因 此,客户端决定刷新其本地缓存并发现其他新注册的实例可能需要30秒。
LoadBalancer Refresh
Ribbon的负载平衡器从本地的Eureka Client获取服务注册列表信息。Ribbon本身还维护本地缓存,以避免为每个请求调用本地客户端。 此缓存每30秒刷新一次(可由ribbon.ServerListRefreshInterval配置)。 所以,可能需要30多秒才能使用新注册的实例。
综上几个因素,一个新注册的实例,特别是启动较快的实例(默认延迟40秒注册),不能马上被Eureka Server发现。另外,刚注册的Eureka Client也不能立即被其他服务调用,因为调用方因为各种缓存没有及时的获取到新的注册列表。

Eureka的自我保护机制

当一个新的Eureka Server出现时,它尝试从相邻节点获取所有实例注册表信息。如果从Peer节点获取信息时出现问题,Eureka Serve会尝试其他的Peer节点。如果服务器能够成功获取所有实例,则根据该信息设置应该接收的更新阈值。如果有任何时间,Eureka Serve接收到的续约低于为该值配置的百分比(默认为15分钟内低于85%),则服务器开启自我保护模式,即不再剔除注册列表的信息。
这样做的好处就是,如果是Eureka Server自身的网络问题,导致Eureka Client的续约不上,Eureka Client的注册列表信息不再被删除,也就是Eureka Client还可以被其他服务消费。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值