SpringBoot + Disruptor的学习

我们使用Disruptor做消息队列的学习,我们做一个简单的记录。

1.添加依赖

<!--Disruptor-->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.3.4</version>
</dependency>

2.消息体Model

import lombok.Data;

/**
 * @author qx
 * @date 2023-05-04
 * @Descripion: 消息体Model
 */
@Data
public class MessageModel {
    private String message;
}

3.构造EventFactory

import com.lmax.disruptor.EventFactory;

/**
 * @author qx
 * @date 2023-05-04
 * @Descripion: 构造EventFactory
 */
public class HelloEventFactory implements EventFactory<MessageModel> {
    @Override
    public MessageModel newInstance() {
        return new MessageModel();
    }
}

4.构造EventHandler-消费者

import com.lmax.disruptor.EventHandler;
import lombok.extern.slf4j.Slf4j;

/**
 * @author qx
 * @date 2023-05-04
 * @Descripion: 构造EventHandler-消费者
 */
@Slf4j
public class HelloEventHandler implements EventHandler<MessageModel> {
    @Override
    public void onEvent(MessageModel messageModel, long l, boolean b) throws Exception {
        Thread.sleep(1000);
        log.info("消费者处理消息开始");
        if (messageModel != null){
            log.info("消费者消费的消息是:{}",messageModel);
        }
        log.info("消费者处理消息结束");
    }
}

5.构造BeanManager

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author qx
 * @date 2023-05-04
 * @Descripion: 构造BeanManager
 */
@Component
public class BeanManager implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    @Override
    public  void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        BeanManager.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }

    public static Object getBean(String name){
        return applicationContext.getBean(name);
    }

    public static <T> T getBean(Class<T> tClass){
        return applicationContext.getBean(tClass);
    }
}

6.构造MQManager

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 java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author qx
 * @date 2023-05-04
 * @Descripion: 构造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;
    }
}

7.构造Mqservice和实现类-生产者

/**
 * @author qx
 * @date 2023-05-04
 * @Descripion:  构造Mqservice
 */
public interface DisruptorMqService {

    /**
     * 消息
     * @param message 消息内容
     */
    void sayHelloMq(String message);

}
import com.lmax.disruptor.RingBuffer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author 秦迅
 * @date 2023-05-04
 * @Descripion: 构造Mqservice实现类
 */
@Service
@Slf4j
public class DisruptorMqServiceImpl implements DisruptorMqService{

    @Autowired
    private RingBuffer<MessageModel> messageModelRingBuffer;

    @Override
    public void sayHelloMq(String message) {
        log.info("record the message: {}",message);
        //获取下一个Event槽的下标
        long sequence = messageModelRingBuffer.next();
        try {
            //给Event填充数据
            MessageModel event = messageModelRingBuffer.get(sequence);
            event.setMessage(message);
            log.info("往消息队列中添加消息:{}", event);
        } catch (Exception e) {
            log.error("failed to add event to messageModelRingBuffer for : e = {},{}",e,e.getMessage());
        } finally {
            //发布Event,激活观察者去消费,将sequence传递给改消费者
            //注意最后的publish方法必须放在finally中以确保必须得到调用;如果某个请求的sequence未被提交将会堵塞后续的发布操作或者其他的producer
            messageModelRingBuffer.publish(sequence);
        }
    }
}

8.构造测试类及方法

import com.example.disruptordemo.disruptor.DisruptorMqService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@Slf4j
@SpringBootTest
class DisruptorDemoApplicationTests {

    @Autowired
    private DisruptorMqService disruptorMqService;

    @Test
    void contextLoads() throws InterruptedException {
        disruptorMqService.sayHelloMq("发送测试消息");
        log.info("消息队列已经发送完毕");
        //这里停止2000ms是为了确定是处理消息是异步的
        Thread.sleep(2000);
    }

}

结果

2023-05-04 12:10:34.689  INFO 7856 --- [           main] c.e.d.disruptor.DisruptorMqServiceImpl   : record the message: 发送测试消息
2023-05-04 12:10:34.691  INFO 7856 --- [           main] c.e.d.disruptor.DisruptorMqServiceImpl   : 往消息队列中添加消息:MessageModel(message=发送测试消息)
2023-05-04 12:10:34.691  INFO 7856 --- [           main] c.e.d.DisruptorDemoApplicationTests      : 消息队列已经发送完毕
2023-05-04 12:10:35.691  INFO 7856 --- [pool-1-thread-1] c.e.d.disruptor.HelloEventHandler        : 消费者处理消息开始
2023-05-04 12:10:35.691  INFO 7856 --- [pool-1-thread-1] c.e.d.disruptor.HelloEventHandler        : 消费者消费的消息是:MessageModel(message=发送测试消息)
2023-05-04 12:10:35.692  INFO 7856 --- [pool-1-thread-1] c.e.d.disruptor.HelloEventHandler        : 消费者处理消息结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qinxun2008081

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值