浅析Disruptor高性能线程消息传递并发框架
作者:kl 发布时间:2023-02-26 14:09:01
前言碎语
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。
来源:http://www.kailing.pub/article/index/arcid/208.html


猜你喜欢
- 本文实例为大家分享了Android实现ListView下拉刷新上拉加载更多的具体代码,供大家参考,具体内容如下其实谷歌官方目前已经推出Lis
- 今天使用jenkins构建时,报以下错误[ERROR] Failed to execute goal on project saas20:
- 首先,通过代码定义一个委托和下面三个示例将要调用的方法:public delegate int AddHandler(int a,int b
- 新手学习记录。写在springboot test 示例 示例代码地址看结尾。后面有带页面的示例。SpringBoot Test无
- 前言代码生成器,也叫逆向工程,是根据数据库里的表结构,自动生成对应的实体类、映射文件和接口。看到很多小伙伴在为数据库生成实体类发愁,现分享给
- Spring中实现多线程,其实非常简单,只需要在配置类中添加@EnableAsync就可以使用多线程。在希望执行的并发方法中使用@Async
- 如何在WinForm中请求发送HTTP手工发送HTTP请求主要是调用 System.Net的HttpWebResponse方法手工发送HTT
- final可以修饰类 ,成员变量,局部变量和方法。1.final修饰成员变量1.final成员变量的初始化对于final修饰的变量,系统不会
- 一、概述现在大多数的电商APP的详情页长得几乎都差不多,几乎都是上面一个商品的图片,当你滑动的时候,会有Tab悬浮在上面,这样做用户体验确实
- 实现Runnable 接口比继承Thread 类的方式更好:(1)可以避免由于Java单继承带来的局限性;(2)可以实现业务执行逻辑和数据资
- 本文实例汇总了Java文件操作。分享给大家供大家参考,具体如下:1.创建文件夹//import java.io.*; File myFold
- 提到锁,大家肯定想到的是sychronized关键字。是用它可以解决一切并发问题,但是,对于系统吞吐量要求更高的话,我们这提供几个小技巧。帮
- 背景 我们知道在.NET Framework中存在四种常用的定时器,他们分别是:1 两个是通用的多线程定时器:Syste
- 归并排序里运用到算法里很重要的一个思想——分治法:将原问题分解为几个规模较小但类似于原问题的子问题——《算法导论》。在每一层递归中都有3个步
- 通过反射根据提供的表名、POJO类型、数据对象自动生成sql语句。如名为 User 的JavaBean与名为 user 的数据库表对应,可以
- 导言目前截屏的方法很多,root不适用,要么其他方法就是有局限性,而其中官方给出的方案最好—MediaProjection介绍Android
- using System;using System.Collections.Generic;using System.ComponentMo
- 关于base64编码Encode和Decode编码的几种方式Base64是一种能将任意Binary资料用64种字元组合成字串的方法,而这个B
- 本文为大家分享了Android ViewPager实现图片滑动预览效果展示的具体代码,供大家参考,具体内容如下效果图:滑动前:滑动后:代码非
- Java是垃圾回收语言的一种,其优点是开发者无需特意管理内存分配,降低了应用由于局部故障(segmentation fault)导致崩溃,同