(Nacos源码解析五)Nacos服务事件变动源码解析

Nacos源码解析系列目录

Nacos服务事件变动源码解析

概念

当客户端向服务端注册服务或发送心跳的时候,服务端会推送服务时间变动事件,通过udp协议向客户端通知

1、客户端注册事件变动

下面的源码流程为注册的实例数据从阻塞队列中取出并更新到了cluster的ephemeralInstances 属性最后会发布服务变动事件,Nacos注册源码解析见
(Nacos源码解析一)Nacos 注册实例源码解析
com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl.Notifier#run
com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl.Notifier#handle
com.alibaba.nacos.naming.core.Service#onChange
com.alibaba.nacos.naming.core.Service#updateIPs

public void updateIPs(Collection<Instance> instances, boolean ephemeral) {
    ...
    // 发布事件 
    getPushService().serviceChanged(this);
    ...
}

2、客户端心跳机制事件变动

下面的源码流程为处理客户端发送的心跳请求,开启一个定时任务,更新实例的最后心跳时间,最后发布服务变动事件,Nacos心跳机制见
(Nacos源码解析三)Nacos 心跳机制源码解析
com.alibaba.nacos.naming.controllers.InstanceController#beat
com.alibaba.nacos.naming.core.Service#processClientBeat
com.alibaba.nacos.naming.healthcheck.ClientBeatProcessor#run

  @Override
    public void run() {
        Service service = this.service;
        if (Loggers.EVT_LOG.isDebugEnabled()) {
            Loggers.EVT_LOG.debug("[CLIENT-BEAT] processing beat: {}", rsInfo.toString());
        }
        
        String ip = rsInfo.getIp();
        String clusterName = rsInfo.getCluster();
        int port = rsInfo.getPort();
        // 获取集群
        Cluster cluster = service.getClusterMap().get(clusterName);
        // 获取集群下全部实例
        List<Instance> instances = cluster.allIPs(true);
        
        for (Instance instance : instances) {
            if (instance.getIp().equals(ip) && instance.getPort() == port) {
                if (Loggers.EVT_LOG.isDebugEnabled()) {
                    Loggers.EVT_LOG.debug("[CLIENT-BEAT] refresh beat: {}", rsInfo.toString());
                }
                // 更新最后心跳时间
                instance.setLastBeat(System.currentTimeMillis());
                if (!instance.isMarked()) {
                    if (!instance.isHealthy()) {
                        instance.setHealthy(true);
                        Loggers.EVT_LOG
                                .info("service: {} {POS} {IP-ENABLED} valid: {}:{}@{}, region: {}, msg: client beat ok",
                                        cluster.getService().getName(), ip, port, cluster.getName(),
                                        UtilsAndCommons.LOCALHOST_SITE);
                        // 发布服务变动事件
                        getPushService().serviceChanged(service);
                    }
                }
            }
        }
    }

3、Spring发布服务变更事件

public void serviceChanged(Service service) {
    // merge some change events to reduce the push frequency:
    if (futureMap
            .containsKey(UtilsAndCommons.assembleFullServiceName(service.getNamespaceId(), service.getName()))) {
        return;
    }
    // 发布服务变更事件
    this.applicationContext.publishEvent(new ServiceChangeEvent(this, service));
}

4、处理服务变更事件,通过udp协议向客户端推送变更数据

com.alibaba.nacos.naming.push.PushService#onApplicationEvent

@Override
public void onApplicationEvent(ServiceChangeEvent event) {
    Service service = event.getService();
    String serviceName = service.getName();
    String namespaceId = service.getNamespaceId();
    
    ...
    // 封装信息
    // 向客户端推送变更的信息
    udpPush(ackEntry);
   ... 
}

com.alibaba.nacos.naming.push.PushService#udpPush

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

janyxe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值