一、Disruptor并发框架简介 能够以很低的延迟,产生大量的交易,建立在JVM平台上,核心是一个业务逻辑的处理器,它能够在一个线程里每秒处理六百万订单。业务逻辑处理器是完全运行在内存中,使用事件源驱动方式。能够在无锁的情况下,实现网络Queue并发操作。    Disruptor是一个高性能的异步处理框架,或者认为是最快的消息处理框架(轻量JMS java message serverice),也可以认为是以一个观察者的模式实现,也可以任务是以一个监听者的模式实现。你可以理解为他是一种高效的"生产者-消费者"模型。也就性能远远高于传统的BlockingQueue容器。 二、Disruptor设计思想 环形数组结构 为了避免垃圾回收,采用数组而非链表。同时,数组对处理器的缓存机制更加友好。 元素位置定位 数组长度2^n,通过位运算,加快定位的速度。下标采取递增的形式。不用担心index溢出的问题。index是long类型,即使100万QPS的处理速度,也需要30万年才能用完。 无锁设计 每个生产者或者消费者线程,会先申请可以操作的元素在数组中的位置,申请到之后,直接在该位置写入或者读取数据。 下面忽略数组的环形结构,介绍一下如何实现无锁设计。整个过程通过原子变量CAS,保证操作的线程安全。

三、Disruptor内部的一些构件简介 1、RingBuffer:Disruptor底层数据结构实现,核心类,是线程间交换数据的中转地。 2、Sequencer:序号管理器,生产同步的实现者,负责消费者/生产者各自序 号、序号栅栏的管理和协调,Sequencer有单生产者,多生产者两种不同的模式,里面实现了各种同步的算法。 3、Sequence:序号,声明一个序号,用于跟踪ringbuffer中任务的变化和消费者的消费情况,disruptor里面大部分的并发代码都是通过对Sequence的值同步修改实现的,而非锁,这是disruptor高性能的一个主要原因。 4、SequenceBarrier:序号栅栏,管理和协调生产者的游标序号和各个消费者的 序号,确保生产者不会覆盖消费者未来得及处理的消息,确保存在依赖的消费者之间能够按照正确的顺序处理, Sequence Barrier是由Sequencer创建的,并被 Processor持有。 5、EventProcessor:事件处理器,监听RingBuffer的事件,并消费可用事件, 从RingBuffer读取的事件会交由实际的生产者实现类来消费;它会一直监听下一个可用的序号,直到该序号对应的事件已经准备好。 5、EventHandler:业务处理器,是实际消费者的接口,完成具体的业务逻辑实 现,第三方实现该接口;代表着消费者。 6、Producer:生产者接口,第三方线程充当该角色,producer向RingBuffer写 入事件。 7、Wait Strategy:Wait Strategy决定了一个消费者怎么等待生产者将事件 (Event)放入Disruptor中。

三、框架如何使用

  1. 新建一个springBoot项目 并在依赖中引入该依赖
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.2</version>
        </dependency>

  1. 编写配置类
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import zk.esl.tool.common.Constants;
import zk.esl.tool.pojo.Consumer;
import zk.esl.tool.pojo.MessageEvent;

import javax.annotation.Resource;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author by LiXinF
 * @date 2023-07-31 17:31
 */

@Configuration
public class DisruptorConfiguration {


    @Resource(name = Constants.ASYNC_SERVICE_EXECUTOR_BEAN_NAME)
    private Executor executor;


    @Bean("MessageVo")
    public RingBuffer<MessageEvent> disruptor() {


        //指定事件工厂
        MessageFactory factory = new MessageFactory();

        //指定ringbuffer字节大小,必须为2的N次方(能将求模运算转为位运算提高效率),否则将影响效率
        int bufferSize = 1024 * 1024;

        //单线程模式,获取额外的性能
        Disruptor<MessageEvent> disruptor = new Disruptor<>(factory, bufferSize, executor,
                ProducerType.SINGLE, new BlockingWaitStrategy());

        //设置事件业务处理器---消费者
        disruptor.handleEventsWith(new Consumer());

        // 启动disruptor线程
        disruptor.start();

        //获取ringbuffer环,用于接取生产者生产的事件

        return disruptor.getRingBuffer();
    }


}
  1. 编写消息工厂 以及实体类
package zk.esl.tool.configuration;


import com.lmax.disruptor.EventFactory;
import org.springframework.stereotype.Component;
import zk.esl.tool.pojo.MessageEvent;

/**
 * @author by LiXinF
 * @date 2023-07-31 17:15
 */

@Component
public class MessageFactory implements EventFactory<MessageEvent> {


    @Override
    public MessageEvent newInstance() {
        return new MessageEvent();
    }
}


package zk.esl.tool.pojo;

import lombok.Data;

/**
 * @author by LiXinF
 * @date 2023-07-31 17:14
 */
@Data
public class MessageEvent {

    private ItemImportParams message; // 可根据自己实际需求修改 String pojo list 

}

  1. 编写生产者
package zk.esl.tool.service;

import zk.esl.tool.pojo.ItemImportParams;

/**
 * @author by LiXinF
 * @date 2023-07-31 18:39
 */
public interface Sys {

     void sayMessage(ItemImportParams itemImportParams);

}


package zk.esl.tool.service.impl;


import com.lmax.disruptor.RingBuffer;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import zk.esl.tool.pojo.ItemImportParams;
import zk.esl.tool.pojo.MessageEvent;
import zk.esl.tool.service.Sys;

import javax.annotation.Resource;

/**
 * @author by LiXinF
 * @date 2023-07-31 18:40
 */

@Service
@Component
public class SysImpl implements Sys {

    @Resource
    private RingBuffer<MessageEvent> MessageVoRingBuffer;




    @Override
    public void sayMessage(ItemImportParams message) {
        long sqe = MessageVoRingBuffer.next();
        try{
            MessageEvent event = MessageVoRingBuffer.get(sqe);
            event.setMessage(message);
        }catch (Exception e){
            System.out.println("e = " + e);
        }finally {
            MessageVoRingBuffer.publish(sqe);
        }
    }
}
  1. 编写消费者
package zk.esl.tool.pojo;

import com.lmax.disruptor.EventHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import zk.esl.tool.template.GeneralItemImportTemplate;


/**
 * @author by LiXinF
 * @date 2023-07-31 17:35
 */
@Slf4j
@Component
public class Consumer implements EventHandler<MessageEvent>{

    @Override
    public void onEvent(MessageEvent messageEvent, long l, boolean b) throws Exception {
        log.info("========数据到达==========");
        GeneralItemImportTemplate generalItemImportTemplate = new GeneralItemImportTemplate();
        generalItemImportTemplate.itemSyn(messageEvent.getMessage()) ;
    }
}