淺析Disruptor高性能線程消息傳遞并發(fā)框架
前言碎語
Disruptor是英國LMAX公司開源的高性能的線程間傳遞消息的并發(fā)框架,和jdk中的BlockingQueue非常類似,但是性能卻是BlockingQueue不能比擬的,下面是官方給出的一分測試報告,可以直觀的看出兩者的性能區(qū)別:


Disruptor 項(xiàng)目地址:https://github.com/LMAX-Exchange/disruptor
核心概念?
這么性能炸裂的框架肯定要把玩一番,試用前,我們先了解下disruptor的主要的概念,然后結(jié)合樓主的weblog項(xiàng)目(之前使用的BlockingQueue),來實(shí)踐下
RingBuffer:環(huán)形的緩沖區(qū),消息事件信息的載體。曾經(jīng) RingBuffer 是 Disruptor 中的最主要的對象,但從3.0版本開始,其職責(zé)被簡化為僅僅負(fù)責(zé)對通過 Disruptor 進(jìn)行交換的數(shù)據(jù)(事件)進(jìn)行存儲和更新。在一些更高級的應(yīng)用場景中,Ring Buffer 可以由用戶的自定義實(shí)現(xiàn)來完全替代。
Event:定義生產(chǎn)者和消費(fèi)者之間進(jìn)行交換的數(shù)據(jù)類型。
EventFactory:創(chuàng)建事件的工廠類接口,由用戶實(shí)現(xiàn),提供具體的事件
EventHandler:事件處理接口,由用戶實(shí)現(xiàn),用于處理事件。
目前為止,我們了解以上核心內(nèi)容即可,更多的詳情,可以移步wiki文檔:https://github.com/LMAX-Exchange/disruptor
核心架構(gòu)圖:

實(shí)踐Disruptor
改造boot-websocket-log項(xiàng)目,這是一個典型的生產(chǎn)者消費(fèi)者模式的實(shí)例。然后將BlockingQueue替換成Disruptor,完成功能,有興趣的可以對比下。
第一步,定義事件類型
/**
* Created by kl on 2018/8/24.
* Content :進(jìn)程日志事件內(nèi)容載體
*/
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 :進(jìn)程日志事件工廠類
*/
public class LoggerEventFactory implements EventFactory{
@Override
public LoggerEvent newInstance() {
return new LoggerEvent();
}
}第三步,定義數(shù)據(jù)處理器
/**
* Created by kl on 2018/8/24.
* Content :進(jìn)程日志事件處理器
*/
@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());
}
}第四步,創(chuàng)建Disruptor實(shí)操類,定義事件發(fā)布方法,發(fā)布事件
/**
* Created by kl on 2018/8/24.
* Content :Disruptor 環(huán)形隊(duì)列
*/
@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);
}
}
}文末結(jié)語
以上四步已經(jīng)完成了Disruptor的使用,啟動項(xiàng)目后就會不斷的發(fā)布日志事件,處理器會將事件內(nèi)容通過websocket傳送到前端頁面上展示,
boot-websocket-log項(xiàng)目地址:https://gitee.com/kailing/boot-websocket-log
Disruptor是高性能的進(jìn)程內(nèi)線程間的數(shù)據(jù)交換框架,特別適合日志類的處理。Disruptor也是從https://github.com/alipay/sofa-tracer了解到的,這是螞蟻金服 團(tuán)隊(duì)開源的分布式鏈路追蹤項(xiàng)目,其中日志處理部分就是使用了Disruptor。
以上就是淺析Disruptor高性能線程消息傳遞并發(fā)框架的詳細(xì)內(nèi)容,更多關(guān)于Disruptor線程消息傳遞并發(fā)框架的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決mybatisplus插入報錯argument type mismatch的問題
這篇文章主要介紹了解決mybatisplus插入報錯argument type mismatch的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
接口隔離原則_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了接口隔離原則,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
詳解Java的MyBatis框架與Spring框架整合中的映射器注入
映射器注入方式可以將MyBatis與Spring映射好的XML文件實(shí)現(xiàn)配置共用,這里我們就來詳解Java的MyBatis框架與Spring框架整合中的映射器注入:2016-06-06

