获取环形缓冲区中的当前消息数

Posted

技术标签:

【中文标题】获取环形缓冲区中的当前消息数【英文标题】:Getting the current number of messages in the ring buffer 【发布时间】:2014-12-11 10:14:42 【问题描述】:

我在我的 Web 应用程序中使用 Spring 的反应器模式。在内部,它使用 LMAX 的 RingBuffer 实现作为它的消息队列之一。我想知道是否有任何方法可以动态找出当前的 RingBuffer 占用情况。这将帮助我确定所需的生产者和消费者的数量(以及它们的相对比率),以及作为消息队列的 RingBuffer 是否被最佳使用。 我尝试了 reactor.event.dispatch.Abs​​tractSingleThreadDispatcher 类的 getBacklog(),但它似乎总是给出相同的值:我在实例化时使用的 RingBuffer 的大小反应堆。 任何关于该问题的说明将不胜感激。

【问题讨论】:

【参考方案1】:

使用 com.lmax.disruptor.Sequencer.remainingCapacity() 要访问 Sequencer 的实例,您必须显式创建它以及 RingBuffer

在我的情况下,初始化输出 Disruptor

Disruptor<MessageEvent> outcomingDisruptor = 
    new Disruptor<MessageEvent>(
        MyEventFactory.getInstance(),
        RING_BUFFER_OUT_SIZE, 
        MyExecutor.getInstance(), 
        ProducerType.SINGLE, new BlockingWaitStrategy());

变成

this.sequencer = 
    SingleProducerSequencer(RING_BUFFER_OUT_SIZE, new BlockingWaitStrategy());
RingBuffer ringBuffer = 
    new RingBuffer<MessageEvent>(MyEventFactory.getInstance(), sequencer);
Disruptor<MessageEvent> outcomingDisruptor = 
    new Disruptor<MessageEvent>(ringBuffer, MyExecutor.getInstance());

然后

this.getOutCapacity() 
    return sequencer.remainingCapacity();


更新

小错误:| 我们需要 outMessagesCount 而不是 getOutCapacity

public long outMessagesCount() 
    return RING_BUFFER_OUT_SIZE - sequencer.remainingCapacity();

【讨论】:

但是如果您需要在另一个没有暴露sequencer 的框架内监控破坏者remainingCapacity 怎么办?例如问题在于基于中断器的 log4j2 异步记录器:据我调查,没有有效的方法可以在那里获取sequencer 看起来一种选择是只使用公开的 ringBuffer.remainingCapacity()。 @yetanothercoder 在 log4j2 中有什么方法可以将剩余容量作为 bean 公开吗?【参考方案2】:

mvnrepository(版本 1.1.4 RELEASE)中最新版本的 reactor-core 没有办法动态监控消息队列的状态。但是,在查看github 上的反应器代码后,我发现了 TraceableDelegatingDispatcher,它允许在运行时通过其remainingSlots() 跟踪消息队列(如果底层调度程序实现支持)方法。最简单的选择是编译源代码并使用它。

【讨论】:

以上是关于获取环形缓冲区中的当前消息数的主要内容,如果未能解决你的问题,请参考以下文章

环形缓冲区

如何从 perf_event_open 中的环形缓冲区中检索调用链以获取 PERF_RECORD_SWITCH?

Linux内核的是如何实现环形缓冲区机制的?

单片机环形对接溢出如何处理

DPDK ring库:环形缓冲区的解剖

怎么计算环形缓冲区长度