1、前言
上篇文章讲解的Eureka Client的服务注册功能,以及服务端的一些初始化过程,不明白的小伙伴可以点击这里客户端服务注册功能;这篇文章主要讲解客户端的服务续约及注册表刷新
2、版本说明
SpringCLoud:Greenwich.SR2
JDK:1.8
3、Eureka Client源码
上一篇在讲解服务客户端的时候讲到,会初始化三个线程池,第一个负责给另外两个添加线程任务去执行,这两个线程任务一个是心跳续约,另一个是拉取服务端注册表,我们先来讲解注册表的获取
3.1 定时拉取服务注册信息
首先先看上边所说的初始化的三个线程池,在DiscoveryClient类的构造方法中:
进入到initScheduledTasks方法中查看拉取注册表线程任务
任务通过TimedSupervisorTask进行封装,TimedSupervisorTask实现Runnable接口,查看其run方法
其方法中通过传入的线程池对象对task进行任务调度执行;
通过TimedSupervisorTask的构造可知,拉取注册表的线程为CacheRefreshThread查看CacheRefreshThread.run()方法
继续跟进
3.1.1 查看全量拉取注册表
查看请求方法
又到了WebResource这里了
跳转到服务端接口ApplicationsResource.getContainers方法,不熟悉怎么找到这边的需要先了解一下Jersey框架就明白了
接着进入getValue中查看获取逻辑
读写缓存中的数据在刚开始的时候是没有数据的,服务注册信息都是添加到注册表中的,所以需要有一个添加到readWriteCacheMap中的时机,这个时间是啥时候呢?
还记得getGZIP方法的引用吗,this.responseCache,这个类是ResponseCache的实例,既然有实例必定需要初始化,由于该类是接口,进入实现类ResponseCacheImpl的构造中,看到了readWriteCacheMap的一个引用
进入CacheLoader.load方法中的generatePayload方法,查看缓存生成逻辑
进入全量写入方法
获取到增量数据之后返回给客户端,客户端执行插入操作。如果获取到的数据不为空则下次任务进行增量拉取;如果获取到的数据为空,则下次还进行全量拉取。
3.1.2 查看增量拉取注册表
增量的逻辑和全量逻辑差不多,只是调用的服务端入口方法不一样跳过从缓存中获取值的步骤,直接跳到根据entityName属性生成缓存的步骤,ResponseCacheImpl.generatePayload方法,查看entityName为ALL_APPS_DELTA的逻辑
进入该方法,查看怎么获取增量数据的
到此服务端请求完成,返回客户端,查看客户端逻辑
先看updateDelta方法,该方法中根据ActionType的类型去更新本地注册表信息
更新完成之后判断服务端注册表的hashCode值和本地是否一致,如果不一致,则进行全量数据获取
到此客户端拉取注册表信息完结。
3.2 定时进行服务续约
心跳服务TimedSupervisorTask构造的入参是HeartbeatThread线程进入到该线程查看run方法
然后通过HttpClient的方式调用服务端接口进行服务续约,服务端方法为InstanceResource.renewLease方法
然后AbstractInstanceRegistry.renew真正完成服务续约
到此,服务续约也已经结束。
4、总结
跟踪源码是一件费时的事情,但想要了解必须要花时间去做,吃等苦中苦,才能需要比别人更多的东西。只要大家耐心学习,一定会有收获。
最后欢迎大家指正错误,共同进步。