
com.sghd.common.event.DisruptorEventBusImpl Maven / Gradle / Ivy
The newest version!
package com.sghd.common.event;
import java.lang.management.ManagementFactory;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.EventTranslatorOneArg;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.SleepingWaitStrategy;
import com.lmax.disruptor.WorkHandler;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import com.sghd.common.utils.thread.NamedThreadFactory;
/**
* 事件总线接口的实现类
*/
//@Component
@SuppressWarnings({ "rawtypes", "unchecked" })
public class DisruptorEventBusImpl implements EventBus,
EventBusImplMBean {
private static final Logger logger = LoggerFactory
.getLogger(DisruptorEventBusImpl.class);
/** 注册的事件接收者 */
private ConcurrentHashMap>> receivers = new ConcurrentHashMap<>();
@Autowired(required = false)
@Qualifier("event_queue_size")
private Integer queueSize = 4096;
@Autowired(required = false)
@Qualifier("event_pool_size")
private Integer poolSize = 2;
@Autowired(required = false)
@Qualifier("event_pool_await_time")
private Integer poolAwaitTime = 60;
private ExecutorService pool;
private RingBuffer ringBuffer;
private Disruptor disruptor;
public final static EventFactory FACTORY = new EventFactory() {
@Override
public Event newInstance() {
return new Event<>();
}
};
public static final EventTranslatorOneArg TRANSLATOR = new EventTranslatorOneArg() {
@Override
public void translateTo(Event event, long sequence, Event arg0) {
event.setName(arg0.getName());
event.setBody(arg0.getBody());
}
};
private class RingeventWork implements WorkHandler {
@Override
public void onEvent(Event event) throws Exception {
DisruptorEventBusImpl.this.onEvent(event);
}
};
void onEvent(Event event) {
String name = event.getName();
if (!receivers.containsKey(name)) {
logger.warn("事件[{}]没有对应的接收器", name);
return;
}
for (Receiver> receiver : receivers.get(name)) {
try {
receiver.onEvent(event);
} catch (ClassCastException e) {
logger.error("事件[" + event.getName() + "]对象类型不符合接收器声明", e);
} catch (Throwable t) {
logger.error("事件[" + event.getName() + "]处理时发生异常", t);
}
}
event.setBody(null);
event.setName(null);
}
/**
* 根据配置初始化
*/
@PostConstruct
protected void initialize() {
ThreadGroup threadGroup = new ThreadGroup("事件模块");
NamedThreadFactory threadFactory = new NamedThreadFactory(threadGroup,"事件处理");
pool = Executors.newCachedThreadPool(threadFactory);
disruptor = new Disruptor(FACTORY, queueSize, pool, ProducerType.MULTI,new SleepingWaitStrategy());
RingeventWork[] works = new RingeventWork[poolSize];
for(int i = 0; i < poolSize; i++){
works[i] = new RingeventWork();
}
disruptor.handleEventsWithWorkerPool(works);
ringBuffer = disruptor.start();
// 注册MBean
try {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName(
"com.sghd.common:type=EventBusMBean");
mbs.registerMBean(this, name);
} catch (Exception e) {
logger.error("注册[common-event]的JMX管理接口失败", e);
}
}
/** 销毁方法 */
@PreDestroy
public void destory() {
shutdown();
}
/** 停止状态 */
private volatile boolean stop;
/**
* 关闭事件总线,阻塞方法会等待总线中的全部事件都发送完后再返回
*/
public void shutdown() {
if (isStop())
return;
stop = true;
for (;;) {
if (ringBuffer.remainingCapacity() == ringBuffer.getBufferSize()) {
break;
}
Thread.yield();
}
// 等待线程池关闭
disruptor.shutdown();
pool.shutdown();
logger.error("开始关闭事件总线线程池");
try {
if (!pool.awaitTermination(poolAwaitTime, TimeUnit.SECONDS)) {
logger.error("无法在预计时间内完成事件总线线程池关闭,尝试强行关闭");
pool.shutdownNow();
if (!pool.awaitTermination(poolAwaitTime, TimeUnit.SECONDS)) {
logger.error("事件总线线程池无法完成关闭");
}
}
} catch (InterruptedException e) {
logger.error("事件总线线程池关闭时线程被打断,强制关闭事件总线线程池");
pool.shutdownNow();
}
}
/**
* 检查该事件总线是否已经停止服务
*
* @return
*/
public boolean isStop() {
return stop;
}
@Override
public void post(Event event) {
if (event == null) {
throw new IllegalArgumentException("事件对象不能为空");
}
if (stop) {
throw new IllegalStateException("事件总线已经停止,不能再接收事件");
}
ringBuffer.publishEvent(TRANSLATOR, event);
}
@Override
public void register(String name, Receiver receiver) {
if (name == null || receiver == null) {
throw new IllegalArgumentException("事件名和接收者均不能为空");
}
CopyOnWriteArraySet> set = receivers.get(name);
if (set == null) {
set = new CopyOnWriteArraySet<>();
CopyOnWriteArraySet> prev = receivers.putIfAbsent(name,
set);
set = prev != null ? prev : set;
}
set.add(receiver);
}
@Override
public void unregister(String name, Receiver receiver) {
if (name == null || receiver == null) {
throw new IllegalArgumentException("事件名和接收者均不能为空");
}
CopyOnWriteArraySet> set = receivers.get(name);
if (set != null) {
set.remove(receiver);
}
}
@Override
public void syncPost(Event event) {
String name = event.getName();
if (!receivers.containsKey(name)) {
logger.warn("事件'{}'没有对应的接收器", name);
return;
}
for (Receiver receiver : receivers.get(name)) {
try {
receiver.onEvent(event);
} catch (Exception e) {
logger.error("事件[" + event.getName() + "]处理时发生异常", e);
}
}
}
// JMX管理接口的实现方法
@Override
public int getEventQueueSize() {
// return (int) (ringBuffer.getBufferSize() - ringBuffer
// .remainingCapacity());
return ((ThreadPoolExecutor) pool).getQueue().size();
}
@Override
public int getPoolActiveCount() {
return ((ThreadPoolExecutor) pool).getActiveCount();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy