package com.eloancn.back.schedule.core.boom;
import com.eloancn.back.schedule.core.config.event.EventBusConfig;
import com.eloancn.back.schedule.core.model.ScheduleRecord;
import com.eloancn.back.schedule.core.schedule.CoreSchedule;
import com.eloancn.back.schedule.core.service.RecordQueryService;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.nio.ByteBuffer;
import java.util.UUID;
import java.util.concurrent.*;
/**
* @author famous
*/
@Component
public class ScheduleFocusConfig {
private final static Logger logger = LoggerFactory.getLogger(ScheduleFocusConfig.class);
private int bufferSize = 1024;
private ScheduleFocusEventProducer scheduleFocusEventProducer;
@Autowired
private RecordQueryService recordQueryService;
@Autowired
private CoreSchedule coreSchedule;
/**
* • BlockingWaitStrategy: 对低延迟和吞吐率不像CPU占用那么重要
* • BusySpinWaitStrategy: CPU使用率高,低延迟
* • LiteBlockingWaitStrategy: BlockingWaitStrategy变种,实验性的
* • PhasedBackoffWaitStrategy: Spins, then yields, then waits,不过还是适合对低延迟和吞吐率不像CPU占用那么重要的情况
* • SleepingWaitStrategy: spin, then yield,然后sleep(LockSupport.parkNanos(1L))在性能和CPU占用率之间做了平衡。
* • TimeoutBlockingWaitStrategy: sleep一段时间。 低延迟。
* • YieldingWaitStrategy: 使用spin, Thread.yield()方式
*
* @return
*/
@PostConstruct
private void ScheduleFocusConfig() {
ScheduleFocusEventFactory factory = new ScheduleFocusEventFactory();
Disruptor<ScheduleFocusEvent> disruptor = new Disruptor<>(factory, bufferSize, new CustomThreadFactory());
System.out.println(coreSchedule);
ScheduleFocusEventHandler handler=new ScheduleFocusEventHandler(coreSchedule);
disruptor.handleEventsWith(handler);
disruptor.start();
RingBuffer<ScheduleFocusEvent> ringBuffer = disruptor.getRingBuffer();
scheduleFocusEventProducer=new ScheduleFocusEventProducer(ringBuffer);
}
public void sendAsyncEmail(ScheduleRecord sc) {
scheduleFocusEventProducer.publish(sc);
}
private class CustomThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName(UUID.randomUUID().toString());
t.setUncaughtExceptionHandler(new ScheduleFocusConfig.MyUncaughtExceptionHandler());
return t;
}
}
private class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
logger.info("线程池缓冲队列超出范围抛弃");
}
}
private class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
logger.error("线程池异常捕获打印:{}", ExceptionUtils.getFullStackTrace(e));
}
}
}
package com.eloancn.back.schedule.core.boom;
import com.eloancn.back.schedule.core.model.ScheduleRecord;
import com.eloancn.back.schedule.core.schedule.CoreSchedule;
/**
* @author famous
*
*/
public class ScheduleFocusEvent {
private ScheduleRecord scheduleRecord;
public void set(ScheduleRecord scheduleRecord) {
this.scheduleRecord = scheduleRecord;
}
public ScheduleRecord getScheduleRecord() {
return scheduleRecord;
}
}
package com.eloancn.back.schedule.core.boom;
import com.eloancn.back.schedule.core.model.ScheduleRecord;
import com.lmax.disruptor.EventFactory;
/**
* @author pat
*/
public class ScheduleFocusEventFactory implements EventFactory<ScheduleFocusEvent> {
@Override
public ScheduleFocusEvent newInstance() {
return new ScheduleFocusEvent();
}
}
package com.eloancn.back.schedule.core.boom;
import com.eloancn.back.schedule.core.model.ScheduleRecord;
import com.eloancn.back.schedule.core.schedule.CoreSchedule;
import com.eloancn.back.schedule.core.service.RecordQueryService;
import com.lmax.disruptor.EventHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author famous
*
*/
public class ScheduleFocusEventHandler implements EventHandler<ScheduleFocusEvent>{
private CoreSchedule coreSchedule;
ScheduleFocusEventHandler(CoreSchedule coreSchedule){
this.coreSchedule=coreSchedule;
}
/**
*
* @param event
* @param sequence
* @param endOfBatch
* @throws Exception
*/
@Override
public void onEvent(ScheduleFocusEvent event, long sequence, boolean endOfBatch) throws Exception {
System.out.println(111);
System.out.println(coreSchedule);
System.out.println(222);
System.out.println(event.getScheduleRecord().getId());
coreSchedule.doSchedule(event.getScheduleRecord());
}
}
package com.eloancn.back.schedule.core.boom;
import com.eloancn.back.schedule.core.model.ScheduleRecord;
import com.eloancn.back.schedule.core.schedule.CoreSchedule;
import com.lmax.disruptor.RingBuffer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author famous
*/
public class ScheduleFocusEventProducer {
private RingBuffer<ScheduleFocusEvent> ringBuffer;
ScheduleFocusEventProducer(RingBuffer<ScheduleFocusEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
}
public void publish(ScheduleRecord scheduleRecord) {
long sequence = ringBuffer.next(); // Grab the next sequence
try {
ScheduleFocusEvent event = ringBuffer.get(sequence); // Get the entry in the Disruptor
event.set(scheduleRecord);
} finally {
ringBuffer.publish(sequence);
}
}
}