image.png

Disruptor :

持有 RingBuffer、消费者线程池 Executor、消费者集合 ConsumerRepository 等引用

RingBuffer:

实质基于环形数组的缓存实现,也是创建 sequencer 与定义 WaitStrategy 的入口
概念解析 - 图2
要找到数组中当前序号指向的元素,可以通过 mod 操作:(sequence 序号值) mod 环形数组长度,例如 RingBuffer 为长度为 6,序号值为 20,则当前会取出索引为 2 的数据

Sequence:

可以看做是一个 AtomicLong 原子类用于标识进度,通过顺序递增的序号来编号,管理进行交换的数据(事件),内部解决了不同 Sequence 之间 CPU 缓存伪共享问题
对数据(事件)的处理过程总是沿着序号在环形数组( RingBuffer )中逐个递增处理
一个 Sequence 用于跟踪标识某个特定的事件处理者( RingBuffer / Producer / Consumer )的处理进度

Sequencer:

内部包含 Sequence , 有两个重要实现类 SingleProducerSequencer MultiProducerSequencer
主要实现生产者与消费者之间快速、正确地传递数据的并发算法

SequenceBarrier:

用于保持对 RingBuffer 的 Main Published Sequence ( Producer ) 和 Consumer 之间的平衡关系
还定义了决定 Consumer 是否还有可处理的事件的逻辑

WaitStrategy:

决定一个消费者将如何等待生产者将 Event 置入 Disruptor,主要包括三种实现,通常情况下业务逻辑使用 BlockingWaitStrategy 即可,YieldingWaitStrategy 虽然性能高效但非常占用CPU性能,在高峰期使用该策略执行业务逻辑可能会造成系统异常卡顿

名称 类型 说明
BlockingWaitStrategy 阻塞策略 效率最低,但对CPU消耗最小
在各种不同部署环境中能提供更加一致的性能表现
SleepingWaitStrategy 睡眠策略 性能表现与 BlockingWaitStrategy 类似,但对生产者线程影响最小
适用于类似异步日志的场景
在 32 位 Linux 系统上,源码中的 LockSupport.parkNanos() 实现代价相当昂贵,不推荐使用
YieldingWaitStrategy 竞争策略 性能最好,适用于低延迟系统
在要求极高且事件处理线程数小于CPU逻辑核心数的场景中适用该策略(CPU具有超线程能力)

Event:

需要放入到 Disruptor 的数据单元(实体类),由用户创建

EventProcessor:

主要事件循环,处理 Disruptor 中的 Event,拥有消费者的 Sequence
单消费者模式下实现类为 BatchEventProcessor,包含了 event loop 有效的实现, 通过 run 方法不断轮训获取数据对象,将数据对象交给消费者进行处理,并且将回调一个 EventHandler 接口的实现对象
多消费者模式下实现类为 WorkProcessor

EventHandler:

由用户实现并且代表了 Disruptor 中的一个消费者的接口,消费者逻辑都需要写在这里

WorkProcessor:

确保每个 Sequence 只被一个 processor 消费,在同一个 WorkPooI 中处理多个 WorkProcessor 不会消费同样的 Sequence