Spring boot integrates disruptor

The first step: introduce pom

<dependency>
		<groupId>com.lmax</groupId>
		<artifactId>disruptor</artifactId>
		<version>3.4.2</version>
</dependency>

Step 2: Define MessageModel

@Data
public class MessageModel {
	private String message;
}

 

The third step: message configuration management


@Configuration
public class MQManager {

	@Autowired
	private RedisUtils redisUtils;
	
	@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(redisUtils));

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

		// 获取ringbuffer环,用于接取生产者生产的事件
		RingBuffer<MessageModel> ringBuffer = disruptor.getRingBuffer();

		return ringBuffer;
	}
}

Step 4: Define the factory class

public class HelloEventFactory implements EventFactory<MessageModel> {
	@Override
	public MessageModel newInstance() {
		return new MessageModel();
	}
}

Step 5: Define consumer event handlers


@Slf4j
@Component
public class HelloEventHandler implements EventHandler<MessageModel> {
	
	private RedisUtils redisUtils;
	
	public HelloEventHandler (RedisUtils redisUtils) {
		this.redisUtils = redisUtils;
	}
	
	@Override
	public void onEvent(MessageModel event, long sequence, boolean endOfBatch) {
		try {
			// 这里停止1000ms是为了确定消费消息是异步的
			Thread.sleep(10);
			redisUtils.buriedPointCount("sayHelloMqReceive");
			log.info("消费者处理消息开始");
			if (event != null) {
				log.info("消费者消费的信息是:{}", event);
			}
		} catch (Exception e) {
			log.info("消费者处理消息失败");
		}
		log.info("消费者处理消息结束");
	}
}

The sixth step: specific implementation

public interface DisruptorMqService {

	void sayHelloMq(String message);
}

@Slf4j
@Service
public class DisruptorMqServiceImpl implements DisruptorMqService {

	@Autowired
	private RingBuffer<MessageModel> messageModelRingBuffer;
	@Autowired
	private RedisUtils redisUtils;
	
	
	@Override
	public void sayHelloMq(String message) {
		redisUtils.buriedPointCount("sayHelloMqSend");
		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);
		}
	}

}

 

 

 

Guess you like

Origin blog.csdn.net/Crystalqy/article/details/107238292