【Nacos源码篇(二)】Nacos的事件通知机制

Nacos通过NotifyCenter这个核心类来进行事件的通知流程,接下来会从整体到局部,从源码角度进行分析

开始之前先简要阐述一下事件通知的大致流程:
比如现在是一个服务注册的事件client端(也就是你的服务)通过调用nacos服务的接口,这个时候,nacos就会通过触发NotifyCenter的事件发布方法,此后,会有一个对应这个服务注册事件的事件发布者EventPublisher来对当前事件进行一个广播操作,广播给注册上了这个事件发布者的订阅者们(Subscriber)。这里一共出现了三个重要的类,一是消息通知中心NotifyCenter,二是消息发布者EventPublisher,三是事件订阅者Subscriber,本篇主要是简要梳理流程,其源码会在后续篇章中剖析

事件通知的核心流程

先看看事件通知的核心类:NotifyCenter

    // 通过 NotifyCenter 来发布一些消息,如服务注册,服务断线等等
public class NotifyCenter {
    // 单例
    private static final NotifyCenter INSTANCE = new NotifyCenter();
    
    // key为Event抽象类的子类,我理解为一个事件,
    // 这些values均为 DefaultPublisher/NamingEventPublisher 均实现 EventPublisher 和 Closeable (shutdown方法)
    private final Map<String, EventPublisher> publisherMap = new ConcurrentHashMap<>(16);
    
    // ignore ..
}

谈谈我对publisherMap的理解:
key:
⚡️是事件类的class全限定类名(如:com.alibaba.nacos.naming.core.v2.event.client.ClientEvent.ClientDisconnectEvent)

value:
⚡️ 是一个 EventPublisher接口(两个实现DefaultPublisher/NamingEventPublisher)的实现
⚡️简单来说就是一个发布者

map:
⚡️k-v 就是一个事件->发布者
⚡️NotifyCenter 通过 ConcurrentHashMap 来保存一个事件以及发布者来调用该事件所对应的发布者的相关方法
⚡️事件我们可以理解为一个事件(虽然是废话),简单的理解比如一个服务注销的事件

接下来详细看看EventPublisher的结构

    private final Map<Class<? extends Event>, Set<Subscriber<? extends Event>>> subscribes = new ConcurrentHashMap<>();
    private BlockingQueue<Event> queue;

就掏了两个参数出来唠嗑一下:
queue
⚡️ 显而易见,阻塞队列,存放一个事件对象

subscribes
⚡️ 同样也是一个map,用来存储事件对象
⚡️ key是一个事件的class
⚡️value是一个一组订阅了该事件的Set集合,也就是该类事件的订阅者集合

既然新冒出来了个Subscriber,那么索性看看

public abstract class Subscriber<T extends Event> {
    public abstract void onEvent(T event);
    // ignore others .....
}

核心方法就是 onEvent 方法
⚡️ 就是订阅者的onEvent方法接受一个事件入参,然后进行它的逻辑处理

刚刚出现的这几个类都离不开一个类,那就是Event

public abstract class Event implements Serializable {
    private static final AtomicLong SEQUENCE = new AtomicLong(0);
    private final long sequence = SEQUENCE.getAndIncrement();
    /**
     * 事件序列号,可用于处理事件的序列
     * Event sequence number, which can be used to handle the sequence of events.
     * @return sequence num, It's best to make sure it's monotone.
     */
    public long sequence() {
        return sequence;
    }
}

也就相当于一个标记类,并没有什么具体的实现,其实现包含了这个事件的一些携带信息,比如ClientOperationEvent里面包含了这个事件的一些信息,在订阅者监听到这个事件的时候,就能交给订阅者进行处理

上面的核心代码尽量留个印象,留意那几个关键类和字段,接下来过一过事件通知的流转过程
在这里插入图片描述

图画的可能不太好,先简要描述一下吧:

  1. 比如一个服务注册事件,调用NotifyCenter的静态方法开始发布一个事件,想要通过通知中心发布一个服务注册的消息
  2. 该事件对应一些发布者,这时候会去map里面找这个事件的发布者
  3. 这个事件发布者呢,他有一个阻塞队列queue,专门用来存储事件的
  4. 同时这个发布者也是一个线程,作为一个发布者的同时,也是作为一个线程被保存在NotifyCenter的map里面
  5. 发布者这个线程呢,会不断的从queue里面取事件
  6. 发布者取出事件后,会从它内部的一个map里面找到这个事件的所有的订阅者,判断这个订阅者是需要同步还是异步通知,这里的代码会在事件发布者篇详细阐述!!

至此,NotifyCenter已经光荣的完成了它的事件通知功能
接着细化NotifyCenter,EventPublisher,Subscriber这三个核心大接口

Nacos源码篇

语雀版文档

Nacos源码注释

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值