eureka(二) eureka原理剖析

eureka原理

客户端是如何注册到注册中心的

 在eureka的client与server通讯过程中,client需要把自己的信息发送到server,那么client具体是通过什么方式发送的,又发送了些什么东西呢。

 通过eureka的启动日志可以看到这么一段信息,上面记录了作为client的时候向服务发送注册信息的注册状态。那么我们可以通过这段信息查找到DiscoveryClient类打上断点来看下客户端是如何注册的。

eureka注册信息

 通过断点我们可以看到该方法的调用链,在这里面我们可以清晰的看到,在最初始还是一段spring的容器的初始化,然后通过DefaultLifecycleProcessor来初始化实现了SmartLifecycle接口的EurekaServiceRegistry类,在注册前置操作完毕之后通过通知listener方式初始化一个定时任务线程池来重复执行DiscoveryClient的register记录状态的变更。

eureka注册调用链

 我们现在可以根据下面的方法逻辑来看下client是如何向服务器发送注册信息的,并且可以知道具体发送了一些什么东西。

发送服务信息

 通过DiscoveryClient中的register方法我们可以清楚的看到客户端向服务端发送的实例信息,我们可以看一下在运行时的时候客户端中有些什么信息。

客户端发送实例信息

 由上图我们可以看出发送的信息主要有服务的名称、IP、实例名称及端口信息。具体是通过什么方式发送的,我们可以通过对象的名称看出来是通过http的方式发送。

注册中心又是如何接收客户端的注册请求

 在我们弄清楚客户端发送的注册信息之后,我们可以继续看下注册中心又是如何接收从客户端发送过来的

服务端接收信息

 通过该日志信息我们可以查到AbstractInstanceRegistry类中有个register输出了这条日志。那么同样的方式我们通过断点来查看调用链。

服务端接收信息调用链

 通过调用链我们可以清晰的看到客户端发送注册信息到注册中心,在ApplicationResource#addInstance
对发送过来信息必要参数进行验证之后,最终调用到AbstractInstanceRegistry#register中进行信息注册。该请求接收的方式主要是通过NIO的方式来接收。

注册中心是如何存储注册信息的

 在我们接收到注册信息之后我们需要对注册信息进行存储,在注册中心中是通过一个ConcurrentHashMap来存储的。在第一次注册的时候会判断map是否存在如果不存在的话则会创建一个key为String、value为Lease的ConcurrentHashMap集合对象,并将注册信息存储到该Map中,在之后的注册信息中则刷新该对象中的信息。具体操作逻辑可看下图:

注册信息接收存储

注册中心的高可用机制

 在微服务体系中,注册中心是一个非常重要的服务,如果注册中心宕机了,那么就会造成服务之间的调用无法拿到当时时间点有效的服务器地址,这样就会造成我们各个服务的调用失败,为了保证注册中心的高可用,eureka的注册机制中提供了注册中心的相互注册。在这种情况下如果有一台eureka宕机了,我们可以通过控台来看观察eureka的状态,及时通知相关人员来修复。

 那么具体在eureka中如何实现高可用呢,我们只需要在server端的配置上加上其他server端的注册地址,将该服务器的信息发送到其他server端,这样eureka就形成了一个集群。

eureka高可用方式

 既然我们已经知道是通过这条配置来形成集群的那么我们可以在日志中查找一下,是否有类似的信息。通过下图的日志打印,我们可以找到有这么一个方法PeerEurekaNodes#start打印出了节点信息,那么我们同样通过断点的方式来查看一下调用链及运行逻辑。

eureka集群日志

 通过调用链我们我们查找到这样的一段逻辑,从字面上的意思是初始化eureka节点。在eureka的启动方法中我们可以看到他启动了一个单线程定时任务来做eureka集群节点更新,至于任务执行使用的参数信息这个在后面讲配置的时候会说到。

初始化节点调用
eureka启动

 通过源码的追踪我们知道在第一次更新节点信息的时候创建用于server通讯的JerseyReplicationClient
。在创建的时候会根据配置的属性信息选择是否需要使用ssl,并且将这个通讯客户端封装成一个PeerEurekaNode对象用来指代eureka的远程server服务。

创建eureka节点


 在PeerEurekaNode创建的时候创建数据同步任务处理器ReplicationTaskProcessor、创建批量任务调度器batchingDispatcher及创建单任务调度器nonBatchingDispatcher。

eureka阶段创建具体流程

Eureka集群信息同步机制

 现在我们知道在注册中心集群的各个节点中会存储PeerEurekaNode对象,我们可以通过这些对象来同步各个节点的信息,那么在这些集群节点信息之间又同步了些什么信息呢。我们可以在PeerAwareInstanceRegistryImpl#register中看到在注册之后有个replicateToPeers方法来同步节点信息,在这个方法中我们就看到了PeerEurekaNode对象。

eureka信息同步

 在该方法中我们可以看到他通过一个isReplication参数来表示实例是否为复制的实例,通过这样的方式来防止循环传播。如果不是复制的实例并且存在eureka集群的话则会同步应用名称、id、实例信息。

注册中心剔除服务的机制什么

 在eureka中如果有些服务发生了错误,未正常在注册中心中注销,如果有服务调用到了这些服务就会导致业务无法进行,这时该怎么办。eureka为我们提供了服务剔除机制,主要用于剔除这些异常未正常调用cannel的服务,主要通过EvictionTask中的evict方法来实现。

注册中心服务剔除

 上图就是evict的具体代码,我们来详细说下这里主要做了些什么操作:

  1. 首先他会判断是否开启了自我保护机制,该机制在配置文件中配置。
  2. 如果最后[更新时间 + lease的存活时间 + 补偿时间 < 当前时间]就加入到过期列表,补偿时间的计算如下图,计算方式[当前时间点 - task最近一次执行的时间点 - 清除间隔,小于0则取0]。
获取补偿时间
  1. 计算要剔除的注册服务最大剔除数量,计算方式为[注册服务总数-注册服务总数*自我保护续约百分比阀值],阀值来自配置文件默认0.85。
  2. 通过洗牌算法(Knuth shuffle algorithm)算法来公平剔除服务。
  3. 服务剔除的方法如下图,从服务容器中获取该服务的实例,移除他。将当前服务剔除的操作时间添加到最近关闭服务队列、最近状态更改队列。最后清除缓存。
服务剔除实现

 因为自我保护机制的存在,会延迟才剔除服务,所以我们需要对服务进行降级和熔断才能保证该服务尽量少调用或不调用。

服务消费者如何获取服务信息

 注册中心的作用我们清楚了,那么在服务调用的时候我们需要知道被调用服务器的信息,我们是如何在client中下载到其他服务器的信息呢。

 为了查找client的执行痕迹,我们需要把日志的级别修改debug,我们在client配置文件加上一条配置使日志打印出来[logging.level.root=DEBUG],加上之后我们再运行的时候就可以在注册之后的信息看到如下图的日志信息。

client获取服务信息日志

 根据打印的信息我们可以在对应的日志信息中加上断点查看调用链,通过调用链我们可以看到具体的刷新服务信息的逻辑。通过addInstance方法将服务信息添加到ConcurrentHashMap中。

client获取服务信息调用链
刷新服务信息

 至于如何初始化该刷新任务我们可以通过调用链之一向上可以找到下图方法,在DiscoveryClient#initScheduledTasks方法中可以看到通过配置参数来设置定时执行任务。

初始化刷新服务信息任务

eureka的作用总结

 注册中心主要用于服务的注册发现,可以及时通过admin页面来查看服务状态,方便运维人员及时处理异常服务器。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容