Eureka-client服务注册及更新源码详解

官方wiki:https://github.com/Netflix/eureka/wiki/Eureka-REST-operations

1. 自动注入入口

使用@EnableEurekaClient注解后springboot会自动配置EurekaClientAutoConfiguration,初始化DiscoveryClient

@Bean
public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {
    return new EurekaDiscoveryClient(config, client);
}

DiscoveryClient依赖单例模式的EurekaClient,实例化EurekaClient实现类DiscoveryClient

@Singleton
public class DiscoveryClient implements EurekaClient {

2. DiscoveryClient初始化

DiscoveryClient初始化构造方法
任务调度器
private final ScheduledExecutorService scheduler;
心跳线程池(向eureka-server注册/续约的池子)
// additional executors for supervised subtasks
private final ThreadPoolExecutor heartbeatExecutor;
缓存刷新线程池(从eureka-server拉取和更新注册表信息的池子)
private final ThreadPoolExecutor cacheRefreshExecutor;

// default size of 2 - 1 each for heartbeat and cacheRefresh
scheduler = Executors.newScheduledThreadPool(2,
       new ThreadFactoryBuilder()
               .setNameFormat("DiscoveryClient-%d")
               .setDaemon(true)
               .build());

heartbeatExecutor = new ThreadPoolExecutor(
       1, clientConfig.getHeartbeatExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
       new SynchronousQueue<Runnable>(),
       new ThreadFactoryBuilder()
               .setNameFormat("DiscoveryClient-HeartbeatExecutor-%d")
               .setDaemon(true)
               .build()
);  // use direct handoff

cacheRefreshExecutor = new ThreadPoolExecutor(
       1, clientConfig.getCacheRefreshExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
       new SynchronousQueue<Runnable>(),
       new ThreadFactoryBuilder()
               .setNameFormat("DiscoveryClient-CacheRefreshExecutor-%d")
               .setDaemon(true)
               .build()
);  // use direct handoff

初始化任务调度initScheduledTasks()方法,调用refreshRegistry()方法,再调用fetchRegistry(remoteRegionsModified)

// if源码里面一大堆判断,判断是否初始化;初始化是获取和保存,已经初始化了则做更新
if (true) {
    getAndStoreFullRegistry();
} else {
    getAndUpdateDelta(applications);
}

3. 核心源码

通过http请求获取到信息然后保存或更新到本地
com.netflix.discovery.shared.Applications apps = httpResponse.getEntity();
localRegionApps.set(this.filterAndShuffle(apps));

// 初始化时,获取eureka-server所有注册表信息保存到本地
private Applications filterAndShuffle(Applications apps) {
    if (apps != null) {
        if (isFetchingRemoteRegionRegistries()) {
            Map<String, Applications> remoteRegionVsApps = new ConcurrentHashMap<String, Applications>();
            apps.shuffleAndIndexInstances(remoteRegionVsApps, clientConfig, instanceRegionChecker);
            for (Applications applications : remoteRegionVsApps.values()) {
                applications.shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());
            }
            this.remoteRegionVsApps = remoteRegionVsApps;
        } else {
            apps.shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());
        }
    }
    return apps;
}

com.netflix.discovery.shared.Applications delta = httpResponse.getEntity();
updateDelta(delta);

// 更新时,获取仅有更新的注册表信息到本地进行更新
private void updateDelta(Applications delta) {
    int deltaCount = 0;
    for (Application app : delta.getRegisteredApplications()) {
        for (InstanceInfo instance : app.getInstances()) {
            Applications applications = getApplications();
            String instanceRegion = instanceRegionChecker.getInstanceRegion(instance);
            if (!instanceRegionChecker.isLocalRegion(instanceRegion)) {
                Applications remoteApps = remoteRegionVsApps.get(instanceRegion);
                if (null == remoteApps) {
                    remoteApps = new Applications();
                    remoteRegionVsApps.put(instanceRegion, remoteApps);
                }
                applications = remoteApps;
            }

            ++deltaCount;
            if (ActionType.ADDED.equals(instance.getActionType())) {
                ...新增实例
            } else if (ActionType.MODIFIED.equals(instance.getActionType())) {
                ...修改实例
            } else if (ActionType.DELETED.equals(instance.getActionType())) {
                ...删除实例
            }
        }
    }
    logger.debug("The total number of instances fetched by the delta processor : {}", deltaCount);

    getApplications().setVersion(delta.getVersion());
    getApplications().shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());

    for (Applications applications : remoteRegionVsApps.values()) {
        applications.setVersion(delta.getVersion());
        applications.shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值