最近在研究Disruptor
在springboot中新建一个例子
1、pom.xml
com.disruptor
demo
0.0.1-SNAPSHOT
jar
org.springframework.boot
spring-boot-starter-parent
2.1.1.RELEASE
1.8
UTF-8
org.springframework.boot
spring-boot-starter-web
com.lmax
disruptor
3.4.2
com.google.guava
guava
r09
junit
junit
3.8.1
test
2、BaseQueueHelper
public abstract class BaseQueueHelper,H extends WorkHandler> {
private static List queueHelperList = new ArrayList();
/**
* Disruptor 对象
*/
private Disruptor disruptor;
/**
* RingBuffer
*/
private RingBuffer ringBuffer;
/**
* initQueue
*/
private List initQueue = new ArrayList();
/**
* 队列大小
*
* @return 队列长度,必须是2的幂
*/
protected abstract int getQueueSize();
/**
* 事件工厂
*
* @return EventFactory
*/
protected abstract EventFactory eventFactory();
/**
* 事件消费者
*
* @return WorkHandler[]
*/
protected abstract WorkHandler[] getHandler();
/**
* 初始化
*/
public void init() {
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("DisruptorThreadPool").build();
disruptor = new Disruptor(eventFactory(), getQueueSize(), namedThreadFactory, ProducerType.SINGLE, getStrategy());
disruptor.setDefaultExceptionHandler(new MyHandlerException());
disruptor.handleEventsWithWorkerPool(getHandler());
ringBuffer = disruptor.start();
//初始化数据发布
for (D data : initQueue) {
ringBuffer.publishEvent(new EventTranslatorOneArg() {
public void translateTo(E event, long sequence, D data) {
event.setValue(data);
}
}, data);
}
//加入资源清理钩子
synchronized (queueHelperList) {
if (queueHelperList.isEmpty()) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
for (BaseQueueHelper baseQueueHelper : queueHelperList) {
baseQueueHelper.shutdown();
}
}
});
}
queueHelperList.add(this);
}
}
/**
* 如果要改变线程执行优先级,override此策略. YieldingWaitStrategy会提高响应并在闲时占用70%以上CPU,
* 慎用SleepingWaitStrategy会降低响应更减少CPU占用,用于日志等场景.
*
* @return WaitStrategy
*/
protected abstract WaitStrategy getStrategy();
/**
* 插入队列消息,支持在对象init前插入队列,则在队列建立时立即发布到队列处理.
*/
public synchronized void publishEvent(D data) {
if (ringBuffer == null) {
initQueue.add(data);
return;
}
ringBuffer.publishEvent(new EventTranslatorOneArg() {
public void translateTo(E event, long sequence, D data) {
event.setValue(data);
}
}, data);
}
/**
* 关闭队列
*/
public void shutdown() {
disruptor.shutdown();
}
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
}
}
3、DisruptorConfig
@Configuration
@ComponentScan(value = {"com.disruptor.demo"})
public class DisruptorConfig {
/**
* smsParamEventHandler1
*
* @return SeriesDataEventHandler
*/
@Bean
public SeriesDataEventHandler smsParamEventHandler1() {
return new SeriesDataEventHandler();
}
/**
* smsParamEventHandler2
*
* @return SeriesDataEventHandler
*/
@Bean
public SeriesDataEventHandler smsParamEventHandler2() {
return new SeriesDataEventHandler();
}
/**
* smsParamEventHandler3
*
* @return SeriesDataEventHandler
*/
@Bean
public SeriesDataEventHandler smsParamEventHandler3() {
return new SeriesDataEventHandler();
}
/**
* smsParamEventHandler4
*
* @return SeriesDataEventHandler
*/
@Bean
public SeriesDataEventHandler smsParamEventHandler4() {
return new SeriesDataEventHandler();
}
/**
* smsParamEventHandler5
*
* @return SeriesDataEventHandler
*/
@Bean
public SeriesDataEventHandler smsParamEventHandler5() {
return new SeriesDataEventHandler();
}
/**
* smsParamEventHandler5
*
* @return SeriesDataEventHandler
*/
@Bean
public SeriesDataEventHandler smsParamEventHandler6() {
return new SeriesDataEventHandler();
}
}
4、EventFactory
public class EventFactory implements com.lmax.disruptor.EventFactory {
public SeriesDataEvent newInstance() {
return new SeriesDataEvent();
}
}
5、MyHandlerException
public class MyHandlerException implements ExceptionHandler{
private Logger logger = LoggerFactory.getLogger(MyHandlerException.class);
/*
* (non-Javadoc) 运行过程中发生时的异常
*
* @see
* com.lmax.disruptor.ExceptionHandler#handleEventException(java.lang.Throwable
* , long, java.lang.Object)
*/
public void handleEventException(Throwable ex, long sequence, Object event) {
ex.printStackTrace();
logger.error("process data error sequence ==[{}] event==[{}] ,ex ==[{}]", sequence, event.toString(), ex.getMessage());
}
/*
* (non-Javadoc) 启动时的异常
*
* @see
* com.lmax.disruptor.ExceptionHandler#handleOnStartException(java.lang.
* Throwable)
*/
public void handleOnStartException(Throwable ex) {
logger.error("start disruptor error ==[{}]!", ex.getMessage());
}
/*
* (non-Javadoc) 关闭时的异常
*
* @see
* com.lmax.disruptor.ExceptionHandler#handleOnShutdownException(java.lang
* .Throwable)
*/
public void handleOnShutdownException(Throwable ex) {
logger.error("shutdown disruptor error ==[{}]!", ex.getMessage());
}
}
6、SeriesData
public class SeriesData {
private String deviceInfoStr;
public SeriesData() {
}
public SeriesData(String deviceInfoStr) {
this.deviceInfoStr = deviceInfoStr;
}
public String getDeviceInfoStr() {
return deviceInfoStr;
}
public void setDeviceInfoStr(String deviceInfoStr) {
this.deviceInfoStr = deviceInfoStr;
}
@Override
public String toString() {
return "SeriesData{" +
"deviceInfoStr='" + deviceInfoStr + '\'' +
'}';
}
}
7、SeriesDataEvent
public class SeriesDataEvent extends ValueWrapper {
}
8、SeriesDataEventHandler
public class SeriesDataEventHandler implements WorkHandler {
private Logger logger = LoggerFactory.getLogger(SeriesDataEventHandler.class);
public void onEvent(SeriesDataEvent event) {
if (event.getValue() == null || StringUtils.isEmpty(event.getValue().getDeviceInfoStr())) {
logger.warn("receiver series data is empty!");
}
else if("hello world!".equals(event.getValue().getDeviceInfoStr())) {
logger.info(event.getValue().getDeviceInfoStr());
}else {
logger.error("Hey baby, hello world!");
}
}
}
9、SeriesDataEventQueueHelper
@Component
public class SeriesDataEventQueueHelper extends BaseQueueHelper implements InitializingBean {
private static final int QUEUE_SIZE = 1024;
@Autowired
private List seriesDataEventHandler;
@Override
protected int getQueueSize() {
return QUEUE_SIZE;
}
@Override
protected com.lmax.disruptor.EventFactory eventFactory() {
return new EventFactory();
}
@Override
protected WorkHandler[] getHandler() {
int size = seriesDataEventHandler.size();
SeriesDataEventHandler[] paramEventHandlers = (SeriesDataEventHandler[]) seriesDataEventHandler.toArray(new SeriesDataEventHandler[size]);
return paramEventHandlers;
}
@Override
protected WaitStrategy getStrategy() {
return new BlockingWaitStrategy();
//return new YieldingWaitStrategy();
}
@Override
public void afterPropertiesSet() throws Exception {
this.init();
}
}
10、ValueWrapper
public abstract class ValueWrapper {
private T value;
public ValueWrapper() {}
public ValueWrapper(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
11、使用,新建一个DisruptorController
@RestController
public class DisruptorController {
@Autowired
private SeriesDataEventQueueHelper seriesDataEventQueueHelper;
@GetMapping("/api/test")
public void demo(){
seriesDataEventQueueHelper.publishEvent(new SeriesData(""));
seriesDataEventQueueHelper.publishEvent(new SeriesData("hello world!"));
seriesDataEventQueueHelper.publishEvent(new SeriesData("hello world!"));
seriesDataEventQueueHelper.publishEvent(new SeriesData("hello world!"));
}
@GetMapping("/api/test2")
public void demo2(){
System.out.println("2223333!");
seriesDataEventQueueHelper.publishEvent(new SeriesData(""));
seriesDataEventQueueHelper.publishEvent(new SeriesData("hello world2!"));
seriesDataEventQueueHelper.publishEvent(new SeriesData("hello world!"));
seriesDataEventQueueHelper.publishEvent(new SeriesData("hello world23!"));
}
}