Nacos源码分析

客户端如何发起服务注册?怎么发送服务心跳?(AP模式下)

首先服务注册是在服务启动的时候进行注册的,
我们的应用服务端的application.yml中配置了spring.cloud.nacos.discovery相关的参数:nacos服务端的地址,namespace,cluster-name等

我们的应用服务服务启动的时候,会加载application.yml并解析成NacosDiscoveryProperties类
NacosRegistration类的一个属性就是NacosDiscoveryProperties,所以 NacosRegistration也存放要注册的服务的相关配置信息

服务启动会调用NacosServiceRegistry.register方法:
1.获得服务名,group:有默认分组
2.getNacosInstanceFromRegistration将NacosRegistration封装成一个Instance
3.namingService.registerInstance(serviceId, group, instance) 真正的进行服务注册
4.NacosNamingService.registerInstance
下面展示一些 内联代码片

// 如果是临时实例,进行心跳检测
if (instance.isEphemeral()) {
            BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
            beatReactor.addBeatInfo(groupedServiceName, beatInfo);
        }

//定时发送心跳
 executorService.schedule(new BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS);
// 进行注册
      serverProxy.registerService(groupedServiceName, groupName, instance);

以上是客户端那边的流程
下面是服务端的流程:
1.Instancecontroller.register 服务端的注册入口
2.ServiceManager.registerInstance
首先存放服务的是一个双重Map
Map(namespace, Map(group::serviceName, Service))
service也是一个map,Map<String,cluster>
第一层map的key是一个拼起来的字符串,

createEmptyService----》createServiceIfAbsent—》putServiceAndInit—》service.init()—》HealthCheckReactor.scheduleCheck(clientBeatCheckTask)—》ClientBeatCheckTask.run()方法------在创建服务实例的时候进行服务的心跳检测(线程)

//核心代码
 List<Instance> instances = service.allIPs(true);//获得所有临时实例
            
            // first set health status of instances:
            for (Instance instance : instances) {
                if (System.currentTimeMillis() - instance.getLastBeat() > instance.getInstanceHeartBeatTimeOut()//当前时间与最后实例心跳时间的差值如果大于配置的心跳时间,表示该实例健康状态为false,默认的心跳时间是15s,然后以事件发布的形式通知客户端
) {
                    if (!instance.isMarked()) {
                        if (instance.isHealthy()) {
                            instance.setHealthy(false);
                            Loggers.EVT_LOG
                                    .info("{POS} {IP-DISABLED} valid: {}:{}@{}@{}, region: {}, msg: client timeout after {}, last beat: {}",
                                            instance.getIp(), instance.getPort(), instance.getClusterName(),
                                            service.getName(), UtilsAndCommons.LOCALHOST_SITE,
                                            instance.getInstanceHeartBeatTimeOut(), instance.getLastBeat());
                            getPushService().serviceChanged(service);
                            ApplicationUtils.publishEvent(new InstanceHeartbeatTimeoutEvent(this, instance));
                        }
                    }
                }
            }

代码一直往下走,得到真正的注册逻辑:就是把实例数据放到一个map中
DistroConsistencyServiceImpl.put方法

@Override
    public void put(String key, Record value) throws NacosException {
        onPut(key, value);//tasks.offer(Pair.with(datumKey, action));//放到一个队列里面
        distroProtocol.sync(new DistroKey(key, KeyBuilder.INSTANCE_LIST_KEY_PREFIX), DataOperation.CHANGE,
                globalConfig.getTaskDispatchPeriod() / 2);//然后同步到
    }

//该run方法就是从队列中取数据进行处理
@Override
        public void run() {
            Loggers.DISTRO.info("distro notifier started");
            
            for (; ; ) {
                try {
                    Pair<String, DataOperation> pair = tasks.take();
                    handle(pair);
                } catch (Throwable e) {
                    Loggers.DISTRO.error("[NACOS-DISTRO] Error while handling notifying task", e);
                }
            }
        }
        

// An highlighted block
var foo = 'bar';
// An highlighted block
var foo = 'bar';

服务端这边的心跳:
客户端向服务端这边发送心跳,服务端这边的处理逻辑:
ClientBeatProcessor类,有run方法
获取所有的临时实例,遍历,设置lastBeat,设置healthy属性,然后以事件发布的形式通知??????????????

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值