8 changed files with 259 additions and 5 deletions
@ -0,0 +1,42 @@ |
|||||
|
package com.techsor.datacenter.sender.config; |
||||
|
|
||||
|
import com.lmax.disruptor.BlockingWaitStrategy; |
||||
|
import com.lmax.disruptor.RingBuffer; |
||||
|
import com.lmax.disruptor.dsl.Disruptor; |
||||
|
import com.lmax.disruptor.dsl.ProducerType; |
||||
|
import com.techsor.datacenter.sender.dao.DashboardStatisticsDao; |
||||
|
import com.techsor.datacenter.sender.disruptor.MeasureEvent; |
||||
|
import com.techsor.datacenter.sender.disruptor.MeasureEventFactory; |
||||
|
import com.techsor.datacenter.sender.disruptor.MeasureEventHandler; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
|
||||
|
import java.util.concurrent.Executors; |
||||
|
|
||||
|
@Configuration |
||||
|
public class DisruptorConfig { |
||||
|
|
||||
|
@Bean |
||||
|
public Disruptor<MeasureEvent> measureDisruptor(DashboardStatisticsDao dao) { |
||||
|
|
||||
|
int ringSize = 1024; |
||||
|
|
||||
|
Disruptor<MeasureEvent> disruptor = new Disruptor<>( |
||||
|
new MeasureEventFactory(), |
||||
|
ringSize, |
||||
|
Executors.defaultThreadFactory(), |
||||
|
ProducerType.MULTI, |
||||
|
new BlockingWaitStrategy() |
||||
|
); |
||||
|
|
||||
|
disruptor.handleEventsWith(new MeasureEventHandler(dao)); |
||||
|
disruptor.start(); |
||||
|
|
||||
|
return disruptor; |
||||
|
} |
||||
|
|
||||
|
@Bean |
||||
|
public RingBuffer<MeasureEvent> measureRingBuffer(Disruptor<MeasureEvent> disruptor) { |
||||
|
return disruptor.getRingBuffer(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
package com.techsor.datacenter.sender.disruptor; |
||||
|
|
||||
|
import com.techsor.datacenter.sender.entitiy.StatisticsMeasureInfo; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
@Data |
||||
|
public class MeasureEvent { |
||||
|
private String uploadValue; |
||||
|
private String deviceId; |
||||
|
private StatisticsMeasureInfo info; |
||||
|
private BigDecimal minValue; |
||||
|
private BigDecimal maxValue; |
||||
|
|
||||
|
public void clear() { |
||||
|
uploadValue = null; |
||||
|
deviceId = null; |
||||
|
info = null; |
||||
|
minValue = null; |
||||
|
maxValue = null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,11 @@ |
|||||
|
package com.techsor.datacenter.sender.disruptor; |
||||
|
|
||||
|
import com.lmax.disruptor.EventFactory; |
||||
|
|
||||
|
public class MeasureEventFactory implements EventFactory<MeasureEvent> { |
||||
|
@Override |
||||
|
public MeasureEvent newInstance() { |
||||
|
return new MeasureEvent(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,64 @@ |
|||||
|
package com.techsor.datacenter.sender.disruptor; |
||||
|
|
||||
|
import com.lmax.disruptor.EventHandler; |
||||
|
import com.techsor.datacenter.sender.dao.DashboardStatisticsDao; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class MeasureEventHandler implements EventHandler<MeasureEvent> { |
||||
|
|
||||
|
private final DashboardStatisticsDao dao; |
||||
|
private final List<MeasureEvent> buffer = new ArrayList<>(100); |
||||
|
private final int batchSize = 100; |
||||
|
private long lastFlushTime = System.currentTimeMillis(); |
||||
|
|
||||
|
public MeasureEventHandler(DashboardStatisticsDao dao) { |
||||
|
this.dao = dao; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onEvent(MeasureEvent e, long seq, boolean endOfBatch) { |
||||
|
buffer.add(copyOf(e)); |
||||
|
|
||||
|
// 自动 flush
|
||||
|
if (buffer.size() >= batchSize || System.currentTimeMillis() - lastFlushTime > 1000) { |
||||
|
flush(); |
||||
|
} |
||||
|
|
||||
|
e.clear(); |
||||
|
} |
||||
|
|
||||
|
private MeasureEvent copyOf(MeasureEvent e) { |
||||
|
MeasureEvent m = new MeasureEvent(); |
||||
|
m.setUploadValue(e.getUploadValue()); |
||||
|
m.setDeviceId(e.getDeviceId()); |
||||
|
m.setInfo(e.getInfo()); |
||||
|
m.setMinValue(e.getMinValue()); |
||||
|
m.setMaxValue(e.getMaxValue()); |
||||
|
return m; |
||||
|
} |
||||
|
|
||||
|
private void flush() { |
||||
|
if (buffer.isEmpty()) return; |
||||
|
|
||||
|
try { |
||||
|
dao.measureBatchInsert(buffer); |
||||
|
} catch (Exception ex) { |
||||
|
log.error("batch DB failed", ex); |
||||
|
} |
||||
|
|
||||
|
buffer.clear(); |
||||
|
lastFlushTime = System.currentTimeMillis(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onStart() {} |
||||
|
|
||||
|
@Override |
||||
|
public void onShutdown() { |
||||
|
flush(); // 程序退出 flush
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
package com.techsor.datacenter.sender.disruptor; |
||||
|
|
||||
|
import com.lmax.disruptor.RingBuffer; |
||||
|
import com.techsor.datacenter.sender.entitiy.StatisticsMeasureInfo; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
@Service |
||||
|
@RequiredArgsConstructor |
||||
|
public class MeasureService { |
||||
|
|
||||
|
private final RingBuffer<MeasureEvent> ringBuffer; |
||||
|
|
||||
|
public void write(String uploadValue, |
||||
|
String deviceId, |
||||
|
StatisticsMeasureInfo info, |
||||
|
BigDecimal minValue, |
||||
|
BigDecimal maxValue) { |
||||
|
|
||||
|
long seq = ringBuffer.next(); |
||||
|
try { |
||||
|
MeasureEvent event = ringBuffer.get(seq); |
||||
|
event.setUploadValue(uploadValue); |
||||
|
event.setDeviceId(deviceId); |
||||
|
event.setInfo(info); |
||||
|
event.setMinValue(minValue); |
||||
|
event.setMaxValue(maxValue); |
||||
|
} finally { |
||||
|
ringBuffer.publish(seq); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
Loading…
Reference in new issue