0 启动概览
1 client 启动逻辑~~~~
(1)根据client 配置,初始化一个discovery client。
(2)初始化线程调度器scheduler,拉取注册表的线程池cacheRefreshExecutor,心跳续约线程池heartbeatExecutor,还有网络通信组件eurekaTransport,
(3)调用initScheduledTasks(),启动上面的两个线程池; 偷偷摸摸的在里面初始化了instanceInfoReplicator(注册用),开个线程执行注册,默认40s才向server发请求进行注册(在spring cloud里做了个优化,启动的时候发了个事件,促使一启动就注册,)。
2 eureka client 向server 抓取注册表的逻辑
这里是cacheRefreshExecutor的作用, fetchRegistry(remoteRegionsModified); 触发拉取
(1)全量拉取, getAndStoreFullRegistry();调用 server的 resource :getContainer,放入AtomicReference<Applications> localRegionApps 中。
(2)增量拉取, getAndUpdateDelta(applications);调用 server的 resource :getContainerDifferential。然后调用 updateDelta(delta);
注意,更新完后会计算本地更新后的hash值,跟远端对比,如果hash值不一样,还是会拉全量覆盖。
3 client是如何向server注册的
(1)client注册,在上面discovery client 启动的时候,会起线延迟40s触发, 调用discoveryClient.register();发起http调用 addInstance(),
(2)server 接受请求,registry.register(info, "true".equals(isReplication));作用有三个
a 更新注册表 Map<String, Lease<InstanceInfo>> gMap。写入最近变化queue
b 让两级缓存失效。invalidateCache
c 同步其他server这个注册事件,replicateToPeers
4 eureka server的多级缓存机制,以及过期的过程
(1)在serverContext的初始化中实现二级缓存,读缓存是ConcurrentMap<Key, Value> readOnlyCacheMap ,写缓存是LoadingCache<Key, Value> readWriteCacheMap;同步过程如下
(2)过期
读缓存30s全量复制,写缓存180s失效,之外还有注册,下线,故障摘除引起的过期。
responseCache.invalidate(appName, vipAddress, secureVipAddress); 但注意只是失效写缓存,读缓存还是等自己全量同步。
5 client和server的心跳机制。
(1)client 心跳线程,http调用server的renew
(2)server 的renew,增加心跳次数,修改注册表中对应InstanceInfo的最近心跳时间。
6 client服务正常下线的服务摘除
(1)client端触发shutdown,cancelLease
(2)跟续约一样,先下线自己,再同步到其他server。
注册表移除,cache失效,变化队列queue加上。
7 server的服务故障检测,自动摘除和安全保护机制
(1)eureka 启动中,openForTraffic()的 postInit(),最终evict
(2)evict里,根据开关触发自我保护机制,触发了就不再摘除节点。不触发就根据节点最近心跳时间进行摘除。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。