【Nacos源码篇(五)】Subscriber源码分析


这是事件通知里处理事件的落脚点,也就是事件执行的落地

先贴下接口Subscriber

public abstract class Subscriber<T extends Event> {
    /**
     * 事件执行的落地
     */
    public abstract void onEvent(T event);

    /**
     * 获取当前订阅者订阅的事件的类型
     */
    public abstract Class<? extends Event> subscribeType();
    
    /**
     * 其子类可以来决定是同步还是异步
     */
    public Executor executor() {
        return null;
    }
    
    /**
     * 是否忽略过期事件。
     */
    public boolean ignoreExpireEvent() {
        return false;
    }
}

从接口描述上,就能清晰的了解到这个接口的主流程

SmartSubscriber

Subscriber有一个SmartSubscriber的扩展子类,是用来针对多事件订阅的List<Class<? extends Event>> subscribeTypes() 该方法返回的是这个订阅者所需要订阅的事件列表

----->代码片段1
public abstract class SmartSubscriber extends Subscriber {
    /**
     * 实现该方法,用来返回多订阅的指定集合
     */
    public abstract List<Class<? extends Event>> subscribeTypes();
    
    // ...
}

----->代码片段2
@Component
public class ClientServiceIndexesManager extends SmartSubscriber {
    @Override
    public List<Class<? extends Event>> subscribeTypes() {
        List<Class<? extends Event>> result = new LinkedList<>();
        result.add(ClientOperationEvent.ClientRegisterServiceEvent.class);
        result.add(ClientOperationEvent.ClientDeregisterServiceEvent.class);
        result.add(ClientOperationEvent.ClientSubscribeServiceEvent.class);
        result.add(ClientOperationEvent.ClientUnsubscribeServiceEvent.class);
        result.add(ClientEvent.ClientDisconnectEvent.class);
        return result;
    }
}

----->代码片段3 
public static void registerSubscriber(final Subscriber consumer, final EventPublisherFactory factory) {
        if (consumer instanceof SmartSubscriber) {
            for (Class<? extends Event> subscribeType : ((SmartSubscriber) consumer).subscribeTypes()) {
                if (ClassUtils.isAssignableFrom(SlowEvent.class, subscribeType)) {
                    INSTANCE.sharePublisher.addSubscriber(consumer, subscribeType);
                } else {
                    // For case, producer: defaultPublisher -> consumer: subscriber.
                    addSubscriber(consumer, subscribeType, factory);
                }
            }
            return;
        }
    // ........
}

这里贴了三段代码
⚡️代码片段一,就是SmartSubscriber的抽象List<Class<? extends Event>> subscribeTypes()
⚡️代码片段二,拿某一个该接口的实现举例子,返回了一个List,里面包含了该订阅者订阅的事件类型集合,那么我就可以这样理解,这个接口的返回值所对应的事件,就是该订阅者订阅的事件,通过代码片段三NotifyCenter#registerSubscriber注册
⚡️代码片段三,又回到了NotifyCenter,订阅者注册的时候,首先是先判定了当前订阅者是监听的是否是多事件的,其事件注册的具体细节可以参考NotifyCenter的源码分析

subscribeType

这个接口和上面说的SmartSubscribersubscribeTypes()接口没有多大的区别,只是这个返回的是一个事件,上面的返回的是多个事件

    @Override
    public Class<? extends Event> subscribeType() {
        return Xxxxxxxx.class;
    }

executor

executor()上一篇的EventPublisher在选择通过异步方式还是同步方式的时候就是调用的这里来判定的,我们可以看到这个的默认实现是null

   @Override
    public void notifySubscriber(Subscriber subscriber, Event event) {
        final Runnable job = () -> subscriber.onEvent(event);
        // 判断当前事件是异步还是同步
        final Executor executor = subscriber.executor();
        if (executor != null) {
            // 异步
            executor.execute(job);
        } else {
            try {
                // 同步
                job.run();
            } catch (Throwable e) {
               // ..
            }
        }
    }

⚡️ 所以订阅者如果没有实际的实现executor这个接口,那么事件发布者就是走的同步方式,这里简单的回顾了一下上一篇的事件发布者

ignoreExpireEvent

这个接口的话,可以看下上游的调用处

    @Override
    public void receiveEvent(Event event) {
		// ..
        for (Subscriber subscriber : subscribers) {
            // 是否忽略过期事件
            if (subscriber.ignoreExpireEvent() && lastEventSequence > currentEventSequence) {
                continue;
            }
            // Notify single subscriber for slow event.
            notifySubscriber(subscriber, event);
        }
    }

⚡️ 这段代码是事件发布者里的,是在准备发布广播给订阅者(notifySubscriber)之前,判断的是否需要忽略过期的事件的
⚡️ 订阅者们可以自己去判断是否订阅过期事件,当然这个接口给的默认实现是false

onEvent

最重要的接口最后说
其实也没啥好说的,就随便拿一个实现lou一眼就行

@Component
public class ClientServiceIndexesManager extends SmartSubscriber {
    @Override
    public void onEvent(Event event) {
        if (event instanceof ClientEvent.ClientDisconnectEvent) {
            // 处理客户端断开
            handleClientDisconnect((ClientEvent.ClientDisconnectEvent) event);
        } else if (event instanceof ClientOperationEvent) {
            // 处理客户端操作
            handleClientOperation((ClientOperationEvent) event);
        }
    }
}

● 这里拿的ClientServiceIndexesManager这个类的onEvent方法来举例子,上面也贴出过这个类了(SmartSubscriber接口的描述) 这里接收的Event参数通过判断其实际的类型,来走这个事件所对应的不同的逻辑
Event是事件的抽象类,每个不同的事件都往其自身塞入了其事件所携带的信息,这个抽象类在下一篇描述

Nacos源码篇

语雀版文档

Nacos源码注释

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Nacos 是一个开源的分布式配置中心和服务发现框架,它提供了服务注册、发现、配置管理等功能。下面是对 Nacos 源码的简要分析: 1. 项目结构:Nacos 代码库主要包括 core 模块、config 模块、discovery 模块等。core 模块提供了核心的数据结构和服务注册与发现的功能,config 模块实现了配置管理相关的功能,discovery 模块实现了服务发现的功能。 2. 注册与发现:Nacos 使用了基于 Raft 算法的一致性协议来实现注册与发现功能。核心模块中的 ServerListManager 负责管理服务列表的变更和更新,InstanceEventProcessor 负责处理服务实例事件。服务注册和发现的过程涉及到数据存储和同步,涉及到的类有 LocalServerData、MetadataManager、SnapshotManager 等。 3. 配置管理:Nacos 的配置管理功能由 config 模块实现。核心类是 ConfigServiceImpl,它负责处理配置的读写和监听。在配置写入时,会通过 ConfigChangePublisher 将变更发布给订阅者。ConfigChangeListeners 负责处理配置变更事件。 4. 数据存储:Nacos 的数据存储使用了内置的嵌入式数据库 Derby。Derby 提供了基于文件的持久化存储,用于存储配置数据、注册数据等。 5. 服务路由:Nacos 通过实现了 LoadBalancer 接口来实现服务路由的功能。LoadBalancer 负责选择可用的服务实例,实现了负载均衡的策略。 这只是对 Nacos 源码的简要分析Nacos源码结构比较复杂,涉及到的技术栈也比较丰富。如果你对具体的实现细节有更多的疑问,可以参考 Nacos 的官方文档或者深入阅读源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值