Spring Cloud 2.2.2 源码之五Eureka客户端注册服务

服务注册和续约的大致流程

在这里插入图片描述
先说下服务注册吧,毕竟作为一个提供服务的客户端,注册到注册中心去比较重要,也是第一步。

InstanceInfoReplicator的run

这个就是注册服务的调度方法,首次延迟30秒执行,后面可能会调整。所以严格说他不是一个定时的任务,只是可调节的定时的调度任务。首先进行客户端实例信息刷新,然后看是否有状态改变,有贵爱彼岸的话dirtyTimestamp不为空,有改变就要通知注册中心,所以要去注册,完成之后继续调度任务。

    public void run() {
        try {
            discoveryClient.refreshInstanceInfo();//刷新实例信息

            Long dirtyTimestamp = instanceInfo.isDirtyWithTime();//是否有状态更新过了,有的话获取更新的时间
            if (dirtyTimestamp != null) {//有脏数据,要重新注册
                discoveryClient.register();
                instanceInfo.unsetIsDirty(dirtyTimestamp);//设置更新标记为不更新
            }
        } catch (Throwable t) {
            logger.warn("There was a problem with the instance info replicator", t);
        } finally {
            Future next = scheduler.schedule(this, replicationIntervalSeconds, TimeUnit.SECONDS);
            scheduledPeriodicRef.set(next);
        }
    }

DiscoveryClient的refreshInstanceInfo

这里主要的是刷新状态信息,根据HealthCheckHandler去获取当前实例的状态信息,然后进行设置。

    void refreshInstanceInfo() {
        applicationInfoManager.refreshDataCenterInfoIfRequired();//刷新数据中心,和AWS亚马逊云有关
        applicationInfoManager.refreshLeaseInfoIfRequired();//更新租约信息

        InstanceStatus status;
        try {//获取实例状态
            status = getHealthCheckHandler().getStatus(instanceInfo.getStatus());
        } catch (Exception e) {
            logger.warn("Exception from healthcheckHandler.getStatus, setting status to DOWN", e);
            status = InstanceStatus.DOWN;
        }

        if (null != status) {
            applicationInfoManager.setInstanceStatus(status);
        }
    }

ApplicationInfoManager的setInstanceStatus

主要是这里,首先获取新的状态,然后设置到实例中,内部会有判断,如果是新的就设置标记,返回先前的状态,如果有改变就要进行通知。

  public synchronized void setInstanceStatus(InstanceStatus status) {
        InstanceStatus next = instanceStatusMapper.map(status);//获取下一个新状态
        if (next == null) {
            return;
        }
        //如果状态有改变,会返回先前状态,否则就是null
        InstanceStatus prev = instanceInfo.setStatus(next);
        if (prev != null) {//有改变了才广播
            for (StatusChangeListener listener : listeners.values()) {
                try {
                    listener.notify(new StatusChangeEvent(prev, next));
                } catch (Exception e) {
                    logger.warn("failed to notify listener: {}", listener.getId(), e);
                }
            }
        }
    }

InstanceInfo的setStatus

设置信息,如果是新的就设置更新标记,isInstanceInfoDirty=true,返回先前的状态。

    public synchronized InstanceStatus setStatus(InstanceStatus status) {
        if (this.status != status) {
            InstanceStatus prev = this.status;
            this.status = status;
            setIsDirty();//设置状态更新
            return prev;
        }
        return null;
    }
    public synchronized void setIsDirty() {
        isInstanceInfoDirty = true;
        lastDirtyTimestamp = System.currentTimeMillis();
    }

DiscoveryClient的状态改变事件监听

前面忘记说了DiscoveryClient初始化的时候还创建了一个监听器,监听实例状态改变,如果有改变不为DOWN的话,就会调用instanceInfoReplicator.onDemandUpdate();
在这里插入图片描述

InstanceInfoReplicator的onDemandUpdate

其实这个就是又提交了一个服务注册的任务,里面还是调用InstanceInfoReplicatorrun,把前一个任务取消掉,因为这个scheduler只有一个线程核心线程在执行任务队列的任务,所以前一个任务被取消了,不会循环调度,就只有一个新提交的任务会循环调度。

 public boolean onDemandUpdate() {
        if (rateLimiter.acquire(burstSize, allowedRatePerMinute)) {//满足频率
            if (!scheduler.isShutdown()) {
                scheduler.submit(new Runnable() {//提交新任务
                    @Override
                    public void run() {
                        logger.debug("Executing on-demand update of local InstanceInfo");
    
                        Future latestPeriodic = scheduledPeriodicRef.get();//获取最近的一次任务
                        if (latestPeriodic != null && !latestPeriodic.isDone()) {//如果没完成
                            logger.debug("Canceling the latest scheduled update, it will be rescheduled at the end of on demand update");
                            latestPeriodic.cancel(false);//取消,非强制中断
                        }
    
                        InstanceInfoReplicator.this.run();//启动
                    }
                });
                return true;
            } else {
                logger.warn("Ignoring onDemand update due to stopped scheduler");
                return false;
            }
        } else {
            logger.warn("Ignoring onDemand update due to rate limiter");
            return false;
        }
    }

DiscoveryClient的register

任务执行到这里的时候,会发现dirtyTimestamp不为空了,因为状态被改过了,所以可以进行想注册中心注册了。
在这里插入图片描述
isInstanceInfoDirty已经是true了。

    public synchronized Long isDirtyWithTime() {
        if (isInstanceInfoDirty) {
            return lastDirtyTimestamp;
        } else {
            return null;
        }
    }

在这里插入图片描述
内部最后就是JerseyApplicationClientpost方法。
在这里插入图片描述
注册完了再清楚状态,继续调度。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值