Disruptor是一款java高性能无锁并发处理框架。和JDK中的BlockingQueue有相似处,但是它的处理速度非常快!!!号称“一个线程一秒钟可以处理600W个订单”(反正渣渣电脑是没体会到)。
Disruptor功能十分强大,比如消费者阻塞等待;生产者-消费者一对一、一对多、多对一、多对多;构建消费者串/并行处理链等等。
具体的概念模型可以参考:https://www.cnblogs.com/haiq/p/4112689.html
下面是我基于Disruptor框架封装的工具。采用fluent编码风格,简化了Disruptor的调用。
package com.gravel.demo.test.disruptor;
import com.gravel.demo.test.disruptor.base.EventProducer;
import com.gravel.demo.test.disruptor.base.Publisher;
import com.gravel.demo.test.disruptor.base.PublisherBuilder;
/**
* @Auther: syh
* @Date: 2020/7/8
* @Description: Disruptor 高性能异步处理框架
*/
public class DisruptorTest {
public static void main(String[] args) throws Exception {
builderTest();
}
private static void builderTest() throws Exception {
// 创建多个生产者实例
EventProducer<Domain> producer1 = new EventProducer<>("producer1");
EventProducer<Domain> producer2 = new EventProducer<>("producer2");
// 创建多个消费者实例
DomainConsumer handler1 = new DomainConsumer("handler1");
DomainConsumer handler2 = new DomainConsumer("handler2");
DomainConsumer after1 = new DomainConsumer("after1");
DomainConsumer after2 = new DomainConsumer("after2");
DomainConsumer after3 = new DomainConsumer("after3");
DomainConsumer then = new DomainConsumer("then");
// 创建消息发布者
final Publisher<Domain> publisher = PublisherBuilder.newBuilder()
// 设置线程工厂
// .threadFactory(r -> new Thread(r))
// .threadFactory(new LimitedThreadFactory())
// .threadFactory(Executors.defaultThreadFactory())
// 设置生产类型
// .producerType(ProducerType.SINGLE)
// .producerType(ProducerType.MULTI)
// 设置事件工厂
// .eventFactory(new EventFactory())
// 设置等待策略
// .waitStrategy(new SleepingWaitStrategy())
// .waitStrategy(new YieldingWaitStrategy())
// 设置发布方式
// .publishStrategy(PublishStrategy.TRANSLATOR)
// .publishStrategy(PublishStrategy.NORMAL)
// 设置ringBuffer大小
// .ringSize(1024 * 8)
// 设置异常处理器
.exceptionHandler(new DomainErrorHandler<>())
// 初始化Disruptor, 在配置生产者和消费者之前一定要先初始化。
.disruptor()
// 设置单生产者
// .producer(producer1)
// 配置单个消费者
// .handler(handler1)
// 配置多生产者
.producer(producer1, producer2)
// ====== 设置多个workers或者handlers处理链 start =======
// .worker(handler1)
.handler(handler1, handler2)
.after(handler1).handler(after1)
.after(handler2).handler(after2)
.after(after1, after2).handler(after3)
// .then(after3)
// ====== 设置多个workers或者handlers处理链 end =======
// 启动
.build();
long start = System.currentTimeMillis();
try {
for (int i = 0; i < 500; i++) {
publisher
// 可连续发布
//.publish(new Domain(String.valueOf("a" + i), "init"))
.publish(new Domain(String.valueOf(i), "init"));
}
} finally {
long sleep = 200;
Thread.sleep(sleep);
System.out.println("used time: " + (System.currentTimeMillis() - start - sleep) + "ms");
// 不关闭会一直阻塞等待
publisher.shutdown();
}
}
}
从上面的代码来看,我们封装的工具类入口是Publisher。他可以配置一系列Disruptor需要的参数,如线程工厂(ThreadFactory)、事件工厂(EventFactory)、等待策略(WaitStrategy)、消息生产者(Producer)、消费者(Handler/Worker)等等。
其中消息生产者和消费者是Publisher的关键,所以稍后重点描述。先看看其他PublisherBuilder类。
package com.gravel.demo.test.disruptor.base;
import com.lmax.disruptor.*;
import com.lmax.disruptor.dsl.ProducerType;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
/**
* @Auther: syh
* @Date: 2020/7/8
* @Description:
*/
public class PublisherBuilder {
// Publish 默认参数
private static final int RING_SIZE = 1024 * 8;
private static final ThreadFactory THREAD_FACTORY = Executors.defaultThreadFactory();
private static final WaitStrategy WAIT_STRATEGY = new SleepingWaitStrategy();
private static final com.lmax.disruptor.EventFactory EVENT_FACTORY = new EventFactory();
private static final ProducerType PRODUCER_TYPE = ProducerType.SINGLE;
private static final PublishStrategy PUBLISH_STRATEGY = PublishStrategy.TRANSLATOR;
private com.lmax.disruptor.EventFactory eventFactory;
private ThreadFactory threadFactory;
private WaitStrategy waitStrategy;
private ExceptionHandler exceptionHandler;
private ProducerType type;
private PublishStrategy publishStrategy;
private EventPublisher publisher;
private int ringSize;
public static PublisherBuilder newBuilder() {
return new PublisherBuilder();
}
/**
* 指定ringBuffer size,最好为2的n次方。默认1024*8
*
* @param ringSize
* @return
*/
public PublisherBuilder ringSize(int ringSize) {
this.ringSize = ringSize;
return this;
}
/**
* 指定eventFactory, 默认EventFactory
*
* @param eventFactory
* @param <T>
* @return
*/
public <T> PublisherBuilder eventFactory(com.lmax.disruptor.EventFactory eventFactory)