优化pile_msg_record插入数据

This commit is contained in:
jsowell
2026-07-01 16:30:38 +08:00
parent 06aab00627
commit aa7a9a10d9
5 changed files with 153 additions and 1 deletions

View File

@@ -0,0 +1,99 @@
package com.jsowell.pile.service.impl;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.mapper.PileMsgRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 非交易记录报文保留策略:
* 每个桩的每个帧类型仅保留最近200条删除动作放到后台异步分批执行
* 避免在报文写入主链路上同步删除带来额外延迟。
*/
@Slf4j
@Service
public class PileMsgRecordRetentionService {
private static final String KEEP_FOREVER_FRAME_TYPE = "0x3B";
private static final int RETAIN_COUNT = 200;
private static final int RETENTION_OFFSET = RETAIN_COUNT - 1;
private static final int DELETE_BATCH_SIZE = 500;
private static final int MAX_DELETE_BATCHES_PER_RUN = 20;
private static final long CLEANUP_DELAY_SECONDS = 30L;
private static final long FOLLOW_UP_DELAY_SECONDS = 5L;
@Autowired
private PileMsgRecordMapper pileMsgRecordMapper;
@Autowired
@Qualifier("scheduledExecutorService")
private ScheduledExecutorService scheduledExecutorService;
private final Set<String> pendingCleanupKeys = ConcurrentHashMap.newKeySet();
public void scheduleRetention(String pileSn, String frameType) {
if (StringUtils.isBlank(pileSn) || StringUtils.isBlank(frameType) || KEEP_FOREVER_FRAME_TYPE.equals(frameType)) {
return;
}
this.scheduleRetention(pileSn, frameType, CLEANUP_DELAY_SECONDS);
}
private void scheduleRetention(String pileSn, String frameType, long delaySeconds) {
String key = buildKey(pileSn, frameType);
if (!pendingCleanupKeys.add(key)) {
return;
}
scheduledExecutorService.schedule(() -> runCleanup(key, pileSn, frameType), delaySeconds, TimeUnit.SECONDS);
}
private void runCleanup(String key, String pileSn, String frameType) {
boolean hasMore = false;
try {
hasMore = cleanupGroup(pileSn, frameType);
} catch (Exception e) {
log.error("pile_msg_record清理失败, pileSn:{}, frameType:{}", pileSn, frameType, e);
} finally {
pendingCleanupKeys.remove(key);
}
if (hasMore) {
this.scheduleRetention(pileSn, frameType, FOLLOW_UP_DELAY_SECONDS);
}
}
private boolean cleanupGroup(String pileSn, String frameType) {
Long cutoffId = pileMsgRecordMapper.selectRetentionCutoffId(pileSn, frameType, RETENTION_OFFSET);
if (cutoffId == null) {
return false;
}
int totalDeleted = 0;
for (int i = 0; i < MAX_DELETE_BATCHES_PER_RUN; i++) {
int deleted = pileMsgRecordMapper.deleteOldRecordsBeforeId(pileSn, frameType, cutoffId, DELETE_BATCH_SIZE);
totalDeleted += deleted;
if (deleted < DELETE_BATCH_SIZE) {
if (totalDeleted > 0) {
log.info("pile_msg_record清理完成, pileSn:{}, frameType:{}, deleted:{}", pileSn, frameType, totalDeleted);
}
return false;
}
}
if (totalDeleted > 0) {
log.info("pile_msg_record本轮清理完成, pileSn:{}, frameType:{}, deleted:{}, 将继续异步清理",
pileSn, frameType, totalDeleted);
}
return true;
}
private String buildKey(String pileSn, String frameType) {
return pileSn + "#" + frameType;
}
}

View File

@@ -18,6 +18,7 @@ import com.jsowell.pile.service.OrderBasicInfoService;
import com.jsowell.pile.service.PileMsgRecordService;
import com.jsowell.pile.vo.web.PileCommunicationLogVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -36,6 +37,9 @@ public class PileMsgRecordServiceImpl implements PileMsgRecordService {
@Autowired
private OrderBasicInfoService orderBasicInfoService;
@Autowired
private PileMsgRecordRetentionService pileMsgRecordRetentionService;
@Override
public void save(String pileSn, String connectorCode, String frameType, String jsonMsg, String originalMsg) {
PileMsgRecord pileMsgRecord = PileMsgRecord.builder()
@@ -46,6 +50,7 @@ public class PileMsgRecordServiceImpl implements PileMsgRecordService {
.originalMsg(originalMsg)
.build();
pileMsgRecordMapper.insertSelective(pileMsgRecord);
pileMsgRecordRetentionService.scheduleRetention(pileSn, frameType);
}
@Override
@@ -85,6 +90,7 @@ public class PileMsgRecordServiceImpl implements PileMsgRecordService {
pileMsgRecord.setOriginalMsg(originalMsg);
pileMsgRecord.setCreateTime(DateUtils.getDateTime());
pileMsgRecordMapper.insertSelective(pileMsgRecord);
pileMsgRecordRetentionService.scheduleRetention(pileSn, frameType);
}
// @Override
@@ -178,6 +184,9 @@ public class PileMsgRecordServiceImpl implements PileMsgRecordService {
@Override
public List<PileMsgRecord> queryPileFeedList(String pileSn, String frameType, String transactionCode) {
List<PileMsgRecord> list = pileMsgRecordMapper.queryPileFeedList(pileSn, frameType, transactionCode);
if (CollectionUtils.isEmpty(list) && StringUtils.isNotBlank(transactionCode)) {
list = pileMsgRecordMapper.queryPileFeedListByJsonTransactionCode(pileSn, frameType, transactionCode);
}
log.info("queryPileFeedList - pileSn:{}, frameType:{}, transactionCode:{}, list: {}", pileSn, frameType, transactionCode, list);
return list;
}