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