SpringBoot disruptor高性能隊列使用
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內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 淺析Disruptor高性能線程消息傳遞並發框架
- 從log4j2到Disruptor詳解
- Springboot詳解RocketMQ實現廣播消息流程
- SpringBoot實現異步事件驅動的方法
- SpringBoot實現線程池