8 changed files with 234 additions and 6 deletions
@ -0,0 +1,24 @@ |
|||
package com.techsor.datacenter.sender.disruptor; |
|||
|
|||
import com.techsor.datacenter.sender.entitiy.StatisticsAccumulateInfo; |
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class AccumulateEvent { |
|||
|
|||
private String deviceId; |
|||
private String uploadValue; |
|||
private Double incrementToday; |
|||
private Double incrementMinute; |
|||
private StatisticsAccumulateInfo info; |
|||
|
|||
public void clear() { |
|||
deviceId = null; |
|||
uploadValue = null; |
|||
incrementToday = null; |
|||
incrementMinute = null; |
|||
info = null; |
|||
} |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,10 @@ |
|||
package com.techsor.datacenter.sender.disruptor; |
|||
|
|||
import com.lmax.disruptor.EventFactory; |
|||
|
|||
public class AccumulateEventFactory implements EventFactory<AccumulateEvent> { |
|||
@Override |
|||
public AccumulateEvent newInstance() { |
|||
return new AccumulateEvent(); |
|||
} |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
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 AccumulateEventHandler implements EventHandler<AccumulateEvent> { |
|||
|
|||
private final DashboardStatisticsDao dao; |
|||
|
|||
private final int batchSize = 100; |
|||
|
|||
private final List<AccumulateEvent> buffer = new ArrayList<>(batchSize); |
|||
|
|||
private long lastFlushTime = System.currentTimeMillis(); |
|||
|
|||
public AccumulateEventHandler(DashboardStatisticsDao dao) { |
|||
this.dao = dao; |
|||
} |
|||
|
|||
@Override |
|||
public void onEvent(AccumulateEvent e, long seq, boolean endOfBatch) { |
|||
buffer.add(copyOf(e)); |
|||
|
|||
// 自动 flush:达到批量条数或超过 1 秒未 flush
|
|||
if (buffer.size() >= batchSize || System.currentTimeMillis() - lastFlushTime > 1000) { |
|||
flush(); |
|||
} |
|||
|
|||
e.clear(); |
|||
} |
|||
|
|||
private AccumulateEvent copyOf(AccumulateEvent e) { |
|||
AccumulateEvent a = new AccumulateEvent(); |
|||
a.setDeviceId(e.getDeviceId()); |
|||
a.setUploadValue(e.getUploadValue()); |
|||
a.setIncrementToday(e.getIncrementToday()); |
|||
a.setIncrementMinute(e.getIncrementMinute()); |
|||
a.setInfo(e.getInfo()); |
|||
return a; |
|||
} |
|||
|
|||
private void flush() { |
|||
if (buffer.isEmpty()) return; |
|||
|
|||
try { |
|||
dao.accumulateBatchInsert(buffer); |
|||
} catch (Exception ex) { |
|||
log.error("accumulate batch DB failed", ex); |
|||
} |
|||
|
|||
buffer.clear(); |
|||
lastFlushTime = System.currentTimeMillis(); |
|||
} |
|||
|
|||
@Override |
|||
public void onStart() {} |
|||
|
|||
@Override |
|||
public void onShutdown() { |
|||
flush(); // 程序退出 flush
|
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
package com.techsor.datacenter.sender.disruptor; |
|||
|
|||
import com.lmax.disruptor.RingBuffer; |
|||
import com.techsor.datacenter.sender.entitiy.StatisticsAccumulateInfo; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
@Service |
|||
@RequiredArgsConstructor |
|||
public class AccumulateService { |
|||
|
|||
private final RingBuffer<AccumulateEvent> ringBuffer; |
|||
|
|||
public void write(String uploadValue, |
|||
String deviceId, |
|||
Double incrementToday, |
|||
Double incrementMinute, |
|||
StatisticsAccumulateInfo info) { |
|||
|
|||
long seq = ringBuffer.next(); |
|||
try { |
|||
AccumulateEvent event = ringBuffer.get(seq); |
|||
event.setUploadValue(uploadValue); |
|||
event.setDeviceId(deviceId); |
|||
event.setIncrementToday(incrementToday); |
|||
event.setIncrementMinute(incrementMinute); |
|||
event.setInfo(info); |
|||
} finally { |
|||
ringBuffer.publish(seq); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue