SpringBoot disruptor高性能队列使用

 更新时间:2023年02月02日 16:00:48   作者:ldcaws  
这篇文章主要介绍了SpringBoot disruptor高性能队列使用,Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题

Disruptor是一个高性能队列,常见的还有kafka、rabbitmq等,下面体验一下~

1、Disruptor简介

Disruptor 是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级)。基于 Disruptor 开发的系统单线程能支撑每秒 600 万订单,2010 年在 QCon 演讲后,获得了业界关注。

其特点简单总结如下:

  • 开源的java框架,用于生产者-消费者场景;
  • 高吞吐量和低延迟;
  • 有界队列;

disruptor在github网址为:https://github.com/LMAX-Exchange/disruptor

2、Disruptor概念

  • Ring Buffer:环形的缓冲区,环形数组中的元素采用覆盖方式,避免了jvm的GC;
  • Sequence Disruptor:通过顺序递增的序号来编号管理通过其进行交换的数据(事件),对数据(事件)的处理过程总是沿着序号逐个递增处理;
  • Sequencer:Sequencer 是 Disruptor 的真正核心。此接口有两个实现类 SingleProducerSequencer、MultiProducerSequencer ,它们定义在生产者和消费者之间快速、正确地传递数据的并发算法;
  • Sequence Barrier:用于保持对RingBuffer的 main published Sequence 和Consumer依赖的其它Consumer的 Sequence 的引用;
  • Wait Strategy:定义 Consumer 如何进行等待下一个事件的策略;
  • Event:在 Disruptor 的语义中,生产者和消费者之间进行交换的数据被称为事件(Event)。它不是一个被 Disruptor 定义的特定类型,而是由 Disruptor 的使用者定义并指定;
  • EventProcessor:EventProcessor 持有特定消费者(Consumer)的 Sequence,并提供用于调用事件处理实现的事件循环(Event Loop);
  • EventHandler:定义的事件处理接口,由用户实现,用于处理事件,是 Consumer 的真正实现;
  • Producer:生产者,只是泛指调用 Disruptor 发布事件的用户代码,Disruptor 没有定义特定接口或类型;

3、springboot+disruptor实例

在pom.xml文件中添加依赖

		<dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.3.4</version>
        </dependency>

消息体Model

@Data
public class MessageModel {
    private String message;
}

构造EventFactory

public class HelloEventFactory implements EventFactory<MessageModel> {
    @Override
    public MessageModel newInstance() {
        return new MessageModel();
    }
}

构造消费者

@Slf4j
public class HelloEventHandler implements EventHandler<MessageModel> {
    @Override
    public void onEvent(MessageModel event, long sequence, boolean endOfBatch) {
        try {
            //这里停止1000ms是为了确定消费消息是异步的
            Thread.sleep(1000);
            log.info("消费者处理消息开始");
            if (event != null) {
                log.info("消费者消费的信息是:{}",event);
            }
        } catch (Exception e) {
            log.info("消费者处理消息失败");
        }
        log.info("消费者处理消息结束");
    }
}

构造MQManager

@Configuration
public class MqManager {
    @Bean("messageModel")
    public RingBuffer<MessageModel> messageModelRingBuffer() {
        //定义用于事件处理的线程池, Disruptor通过java.util.concurrent.ExecutorSerivce提供的线程来触发consumer的事件处理
        ExecutorService executor = Executors.newFixedThreadPool(2);
        //指定事件工厂
        HelloEventFactory factory = new HelloEventFactory();
        //指定ringbuffer字节大小,必须为2的N次方(能将求模运算转为位运算提高效率),否则将影响效率
        int bufferSize = 1024 * 256;
        //单线程模式,获取额外的性能
        Disruptor<MessageModel> disruptor = new Disruptor<>(factory, bufferSize, executor, ProducerType.SINGLE, new BlockingWaitStrategy());
        //设置事件业务处理器---消费者
        disruptor.handleEventsWith(new HelloEventHandler());
        //启动disruptor线程
        disruptor.start();
        //获取ringbuffer环,用于接取生产者生产的事件
        RingBuffer<MessageModel> ringBuffer = disruptor.getRingBuffer();
        return ringBuffer;
    }
}

构造生产者

@Configuration
public class MqManager {
    @Bean("messageModel")
    public RingBuffer<MessageModel> messageModelRingBuffer() {
        //定义用于事件处理的线程池, Disruptor通过java.util.concurrent.ExecutorSerivce提供的线程来触发consumer的事件处理
        ExecutorService executor = Executors.newFixedThreadPool(2);
        //指定事件工厂
        HelloEventFactory factory = new HelloEventFactory();
        //指定ringbuffer字节大小,必须为2的N次方(能将求模运算转为位运算提高效率),否则将影响效率
        int bufferSize = 1024 * 256;
        //单线程模式,获取额外的性能
        Disruptor<MessageModel> disruptor = new Disruptor<>(factory, bufferSize, executor, ProducerType.SINGLE, new BlockingWaitStrategy());
        //设置事件业务处理器---消费者
        disruptor.handleEventsWith(new HelloEventHandler());
        //启动disruptor线程
        disruptor.start();
        //获取ringbuffer环,用于接取生产者生产的事件
        RingBuffer<MessageModel> ringBuffer = disruptor.getRingBuffer();
        return ringBuffer;
    }
}

测试

	/**
     * 项目内部使用Disruptor做消息队列
     * @throws Exception
     */
    @Test
    public void sayHelloMqTest() throws Exception{
        helloEventProducer.sayHelloMq("Hello world!");
        log.info("消息队列已发送完毕");
        //这里停止2000ms是为了确定是处理消息是异步的
        Thread.sleep(2000);
    }

运行结果如下

4、小结

引用disruptor作为内部的高性能队列,应用于生产者-消费者模式中还是非常nice的,后面若有工程需求可以尝试一下。

到此这篇关于SpringBoot disruptor高性能队列使用的文章就介绍到这了,更多相关SpringBoot disruptor内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringMVC @RequestBody属性名大写字母注入失败的解决

    SpringMVC @RequestBody属性名大写字母注入失败的解决

    这篇文章主要介绍了SpringMVC @RequestBody属性名大写字母注入失败的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • SpringBoot整合Netty服务端的实现示例

    SpringBoot整合Netty服务端的实现示例

    Netty提供了一套完整的API,用于处理网络IO操作,如TCP和UDP套接字,本文主要介绍了SpringBoot整合Netty服务端的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • SpringBoot种如何使用 EasyExcel 实现自定义表头导出并实现数据格式化转换

    SpringBoot种如何使用 EasyExcel 实现自定义表头导出并实现数据格式化转换

    本文详细介绍了如何使用EasyExcel工具类实现自定义表头导出,并实现数据格式化转换与添加下拉框操作,通过示例和代码,展示了如何处理不同数据结构和注解,确保数据在导出时能够正确显示和格式化,此外,还介绍了如何解决特定数据类型的转换问题,并提供了解决方案
    2024-11-11
  • Java实现锁定某个变量的几种方式示例详解

    Java实现锁定某个变量的几种方式示例详解

    这篇文章主要为大家介绍了Java实现锁某个变量的几种方式示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • mybatis自动生成时如何设置不生成Example类详解

    mybatis自动生成时如何设置不生成Example类详解

    这篇文章主要给大家介绍了关于mybatis自动生成时如何设置不生成Example类的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-05-05
  • JAVA实现网络/本地图片转BASE64存储代码示例

    JAVA实现网络/本地图片转BASE64存储代码示例

    这篇文章主要给大家介绍了关于JAVA实现网络/本地图片转BASE64存储的相关资料,Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法,需要的朋友可以参考下
    2023-07-07
  • 使用Spring从YAML文件读取内容映射为Map方式

    使用Spring从YAML文件读取内容映射为Map方式

    这篇文章主要介绍了使用Spring从YAML文件读取内容映射为Map方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 详解基于redis实现分布式锁

    详解基于redis实现分布式锁

    系统的不断扩大,分布式锁是最基本的保障。与单机的多线程不一样的是,分布式跨多个机器。线程的共享变量无法跨机器。本文将介绍基于redis实现分布式锁。
    2021-06-06
  • Java日常练习题,每天进步一点点(26)

    Java日常练习题,每天进步一点点(26)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • Java实现树形结构管理的组合设计模式

    Java实现树形结构管理的组合设计模式

    Java组合模式是一种结构型设计模式,它允许将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户可以使用统一的方式处理单个对象和对象组合,从而简化了系统的设计和维护
    2023-04-04

最新评论