浅析Disruptor高性能线程消息传递并发框架

 更新时间:2022年03月01日 11:33:53   作者:kl  
这篇文章主要为大家介绍了Disruptor高性能线程消息传递并发框架的简单分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步

前言碎语

Disruptor是英国LMAX公司开源的高性能的线程间传递消息的并发框架,和jdk中的BlockingQueue非常类似,但是性能却是BlockingQueue不能比拟的,下面是官方给出的一分测试报告,可以直观的看出两者的性能区别:


Disruptor 项目地址:https://github.com/LMAX-Exchange/disruptor

核心概念?

这么性能炸裂的框架肯定要把玩一番,试用前,我们先了解下disruptor的主要的概念,然后结合楼主的weblog项目(之前使用的BlockingQueue),来实践下

RingBuffer:环形的缓冲区,消息事件信息的载体。曾经 RingBuffer 是 Disruptor 中的最主要的对象,但从3.0版本开始,其职责被简化为仅仅负责对通过 Disruptor 进行交换的数据(事件)进行存储和更新。在一些更高级的应用场景中,Ring Buffer 可以由用户的自定义实现来完全替代。

Event:定义生产者和消费者之间进行交换的数据类型。

EventFactory:创建事件的工厂类接口,由用户实现,提供具体的事件

EventHandler:事件处理接口,由用户实现,用于处理事件。

目前为止,我们了解以上核心内容即可,更多的详情,可以移步wiki文档:https://github.com/LMAX-Exchange/disruptor

核心架构图:

实践Disruptor

改造boot-websocket-log项目,这是一个典型的生产者消费者模式的实例。然后将BlockingQueue替换成Disruptor,完成功能,有兴趣的可以对比下。

第一步,定义事件类型

/**
 * Created by kl on 2018/8/24.
 * Content :进程日志事件内容载体
 */
public class LoggerEvent {
    private LoggerMessage log;
    public LoggerMessage getLog() {
        return log;
    }
    public void setLog(LoggerMessage log) {
        this.log = log;
    }
}

第二步,定义事件工厂

/**
 * Created by kl on 2018/8/24.
 * Content :进程日志事件工厂类
 */
public class LoggerEventFactory implements EventFactory{
    @Override
    public LoggerEvent newInstance() {
        return new LoggerEvent();
    }
}

第三步,定义数据处理器

/**
 * Created by kl on 2018/8/24.
 * Content :进程日志事件处理器
 */
@Component
public class LoggerEventHandler implements EventHandler{
    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    @Override
    public void onEvent(LoggerEvent stringEvent, long l, boolean b) {
        messagingTemplate.convertAndSend("/topic/pullLogger",stringEvent.getLog());
    }
}

第四步,创建Disruptor实操类,定义事件发布方法,发布事件

/**
 * Created by kl on 2018/8/24.
 * Content :Disruptor 环形队列
 */
@Component
public class LoggerDisruptorQueue {
    private Executor executor = Executors.newCachedThreadPool();
    // The factory for the event
    private LoggerEventFactory factory = new LoggerEventFactory();
    private FileLoggerEventFactory fileLoggerEventFactory = new FileLoggerEventFactory();
    // Specify the size of the ring buffer, must be power of 2.
    private int bufferSize = 2 * 1024;
    // Construct the Disruptor
    private Disruptordisruptor = new Disruptor<>(factory, bufferSize, executor);;
    private DisruptorfileLoggerEventDisruptor = new Disruptor<>(fileLoggerEventFactory, bufferSize, executor);;
    private static  RingBufferringBuffer;
    private static  RingBufferfileLoggerEventRingBuffer;
    @Autowired
    LoggerDisruptorQueue(LoggerEventHandler eventHandler,FileLoggerEventHandler fileLoggerEventHandler) {
        disruptor.handleEventsWith(eventHandler);
        fileLoggerEventDisruptor.handleEventsWith(fileLoggerEventHandler);
        this.ringBuffer = disruptor.getRingBuffer();
        this.fileLoggerEventRingBuffer = fileLoggerEventDisruptor.getRingBuffer();
        disruptor.start();
        fileLoggerEventDisruptor.start();
    }
    public static void publishEvent(LoggerMessage log) {
        long sequence = ringBuffer.next();  // Grab the next sequence
        try {
            LoggerEvent event = ringBuffer.get(sequence); // Get the entry in the Disruptor
            // for the sequence
            event.setLog(log);  // Fill with data
        } finally {
            ringBuffer.publish(sequence);
        }
    }
    public static void publishEvent(String log) {
        if(fileLoggerEventRingBuffer == null) return;
        long sequence = fileLoggerEventRingBuffer.next();  // Grab the next sequence
        try {
            FileLoggerEvent event = fileLoggerEventRingBuffer.get(sequence); // Get the entry in the Disruptor
            // for the sequence
            event.setLog(log);  // Fill with data
        } finally {
            fileLoggerEventRingBuffer.publish(sequence);
        }
    }
}

文末结语

以上四步已经完成了Disruptor的使用,启动项目后就会不断的发布日志事件,处理器会将事件内容通过websocket传送到前端页面上展示,

boot-websocket-log项目地址:https://gitee.com/kailing/boot-websocket-log

Disruptor是高性能的进程内线程间的数据交换框架,特别适合日志类的处理。Disruptor也是从https://github.com/alipay/sofa-tracer了解到的,这是蚂蚁金服 团队开源的分布式链路追踪项目,其中日志处理部分就是使用了Disruptor。

以上就是浅析Disruptor高性能线程消息传递并发框架的详细内容,更多关于Disruptor线程消息传递并发框架的资料请关注脚本之家其它相关文章!

相关文章

  • Java开发常见异常及解决办法详解

    Java开发常见异常及解决办法详解

    这篇文章主要介绍了java程序常见异常及处理汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-09-09
  • java使用异或对文件进行加密解密

    java使用异或对文件进行加密解密

    这篇文章主要为大家详细介绍了java使用异或方式对文件进行加密解密,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • 解决mybatisplus插入报错argument type mismatch的问题

    解决mybatisplus插入报错argument type mismatch的问题

    这篇文章主要介绍了解决mybatisplus插入报错argument type mismatch的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • java邮件收发功能实现代码

    java邮件收发功能实现代码

    这篇文章主要为大家详细介绍了java邮件收发功能实现代码,具有一定的参考价值,感兴趣的朋友可以参考一下
    2016-06-06
  • Servlet实现分页效果

    Servlet实现分页效果

    这篇文章主要为大家详细介绍了Servlet实现分页效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Java多线程之线程状态的迁移详解

    Java多线程之线程状态的迁移详解

    线程状态迁移,又常被称作线程的生命周期,指的是线程从创建到终结需要经历哪些状态,什么情况下会出现哪些状态.线程的状态直接关系着并发编程的各种问题,本文就线程的状态迁移做一初步探讨,并总结在何种情况下会出现这些状态,需要的朋友可以参考下
    2021-06-06
  • SpringBoot中的classpath使用解读

    SpringBoot中的classpath使用解读

    本文详细介绍了SpringBoot中的classpath及其在开发、编译和打包过程中资源管理的方式,特别是在使用Maven构建SpringBoot项目时,资源文件如何从开发环境的resources目录移动到最终JAR包中的BOOT-INF/classes目录,以及SpringBoot如何加载这些资源
    2025-02-02
  • 接口隔离原则_动力节点Java学院整理

    接口隔离原则_动力节点Java学院整理

    这篇文章主要介绍了接口隔离原则,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 详解Java的MyBatis框架与Spring框架整合中的映射器注入

    详解Java的MyBatis框架与Spring框架整合中的映射器注入

    映射器注入方式可以将MyBatis与Spring映射好的XML文件实现配置共用,这里我们就来详解Java的MyBatis框架与Spring框架整合中的映射器注入:
    2016-06-06
  • 详解Java 二叉树的实现和遍历

    详解Java 二叉树的实现和遍历

    二叉树可以简单理解为对于一个节点来说,最多拥有一个上级节点,同时最多具备左右两个下级节点的数据结构。本文将详细介绍一下Java中二叉树的实现和遍历,需要的可以参考一下
    2022-01-01

最新评论