1、webcad异步拆单es数据数量错误修复;2、webcad拆单内存引用上升趋势优化;3、es-orderModel移除sortId;

This commit is contained in:
gaoqr
2025-06-10 14:42:04 +08:00
parent 9418535151
commit 92dbbced03
5 changed files with 101 additions and 66 deletions
@@ -121,6 +121,4 @@ public class OrderModelDO extends ESDocument {
private String remarkJson; // 普通备注(板材数据中)
@Schema(description = "特殊备注(板材数据中)")
private String specialRemark; // 特殊备注(板材数据中)
private Long sortId;
}
@@ -14,6 +14,10 @@ import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.es.core.dal.ESDocument;
import com.cf.imes.module.plan.dal.dataobject.ordermodel.OrderModelDO;
import com.cf.imes.module.plan.dal.elasticsearch.OrderPartsRemark;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -51,6 +55,15 @@ public class OrderInputProcessor {
private static final String FIELD_BATCH_ID = "batchId";
private static ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 跳过 null 字段
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
}
/**
* 保存生产单造型数据
*
@@ -80,26 +93,12 @@ public class OrderInputProcessor {
try {
bulkAsyncCreate(ORDER_PLATE_MODEL, orderModelDOs);
} catch (IOException | ElasticsearchException e) {
log.error(e.getMessage());
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
public void deleteByOrderId(Long orderId, String index) {
DeleteByQueryRequest.Builder builder = new DeleteByQueryRequest.Builder();
builder.index(index);
builder.query(q -> q.term(t -> t.field(FIELD_ORDER_ID).value(orderId)));
try {
DeleteByQueryResponse response = elasticsearchClient.deleteByQuery(builder.build());
log.info("Deleted {} documents with planId {}", response.deleted(), orderId);
} catch (IOException | ElasticsearchException e) {
log.error("Error deleting documents with planId {}: {}", orderId, e.getMessage());
throw new ServiceException(INTERNAL_SERVER_ERROR);
}
}
/**
* 按批次删除生产单OrderModels
*
@@ -179,10 +178,17 @@ public class OrderInputProcessor {
return elasticsearchClient.bulk(br.build());
}
public void bulkAsyncCreate(String idxName, List<? extends ESDocument> documents) throws IOException, ElasticsearchException {
public void bulkAsyncCreate(String idxName, List<OrderModelDO> documents) throws IOException, ElasticsearchException {
BulkRequest.Builder br = new BulkRequest.Builder();
Date date = new Date();
documents.forEach(esDocument -> {
// 深拷贝documents
List<OrderModelDO> deepCopy = objectMapper.readValue(
objectMapper.writeValueAsString(documents),
new TypeReference<>() {
}
);
deepCopy.forEach(esDocument -> {
if (CharSequenceUtil.isBlank(esDocument.getId())) {
esDocument.setId(snowflake.nextIdStr());
}
@@ -194,6 +200,21 @@ public class OrderInputProcessor {
.id(esDocument.getId())
.document(esDocument)));
});
elasticsearchAsyncClient.bulk(br.build());
elasticsearchAsyncClient.bulk(br.build())
.whenComplete((response, exception) -> {
deepCopy.clear();
if (exception != null) {
log.error("ES bulk async failed for index: {}, size: {}, error: {}",
idxName, documents.size(), exception.getMessage(), exception);
} else if (response.errors()) {
log.warn("ES bulk async partially failed for index: {}, size: {}",
idxName, documents.size());
} else {
log.debug("ES bulk async success for index: {}, size: {}",
idxName, documents.size());
}
});
}
}
@@ -192,8 +192,6 @@ public class WebCadOrderImportAsyncFactory {
private String tempFilePath;
private long sortId;
public WebCadOrderImportAsyncFactory(Long organId,
OrderMapper orderMapper,
SnowFlakeGenerator snowFlakeGenerator,
@@ -229,7 +227,6 @@ public class WebCadOrderImportAsyncFactory {
sealEdgeConfigList = new ArrayList<>();
this.cadImportPlateNumThreshold = cadImportPlateNumThreshold;
this.jdbcTemplate = jdbcTemplate;
this.sortId = 1;
}
public void analyzeTempData(Long taskId, String webcadJsonCachePath) throws FileNotFoundException {
@@ -884,7 +881,6 @@ public class WebCadOrderImportAsyncFactory {
.orderId(orderId)
.plateId(plateDO.getId())
.batchId(batchId)
.sortId(sortId++)
.texture(block.getTexture())
.typographicFace(block.getHoleArrange())
.openDoorType(block.getOpenDoorType())
@@ -1819,11 +1815,15 @@ public class WebCadOrderImportAsyncFactory {
if (!isLast) {
// 存储完成清理 list
list.clear();
clearPlate();
}
}
}
private void clearPlate(){
plateDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
}
private void orderItemBatchInsertWithinThreshold(List<OrderItemDO> list, boolean isLast) {
// 达到批量的阈值就做一次插入
if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
@@ -1855,11 +1855,15 @@ public class WebCadOrderImportAsyncFactory {
if (!isLast) {
// 存储完成清理 list
list.clear();
clearItem();
}
}
}
private void clearItem(){
orderItemDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
}
private void orderPartBatchInsertWithinThreshold(List<OrderPartsDO> list, boolean isLast) {
// 达到批量的阈值就做一次插入
if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
@@ -1906,11 +1910,15 @@ public class WebCadOrderImportAsyncFactory {
if (!isLast) {
// 存储完成清理 list
list.clear();
clearPart();
}
}
}
private void clearPart(){
orderPartsDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
}
/**
* 每达到阈值就批量插入一次生产单造型数据和压缩数据
*
@@ -1923,7 +1931,7 @@ public class WebCadOrderImportAsyncFactory {
orderInputProcessor.batchAsyncSaveModel(orderModelDOS);
if (!isLast) {
// 存储完成清理 list
orderModelDOS.clear();
orderModelDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
}
}
}
@@ -2052,21 +2060,21 @@ public class WebCadOrderImportAsyncFactory {
* 清空所有列表
*/
private void clearAll() {
roomBodyMap.clear();
bodyMap.clear();
orderGroupMap.clear();
materialMap.clear();
processGroupMap.clear();
existRoomIdMap.clear();
orderPartMap.clear();
roomBodyMap = null;
bodyMap = null;
orderGroupMap = null;
materialMap = null;
processGroupMap = null;
existRoomIdMap = null;
orderPartMap = null;
plateDOS.clear();
orderItemDOS.clear();
orderPartsDOS.clear();
orderModelDOS.clear();
rawGoodsDOS.clear();
goodsDOS.clear();
sealEdgeConfigList.clear();
plateDOS = null;
orderItemDOS = null;
orderPartsDOS = null;
orderModelDOS = null;
rawGoodsDOS = null;
goodsDOS = null;
sealEdgeConfigList = null;
}
/**
@@ -175,8 +175,6 @@ public class WebCadOrderImportFactory {
// 板件数量是否已达到阈值
private boolean plateNumReachThreshold = false;
private long sortId;
public WebCadOrderImportFactory(Long organId,
OrderDO orderDO,
SnowFlakeGenerator snowFlakeGenerator,
@@ -208,7 +206,6 @@ public class WebCadOrderImportFactory {
sealEdgeConfigList = new ArrayList<>();
this.cadImportPlateNumThreshold = cadImportPlateNumThreshold;
this.jdbcTemplate = jdbcTemplate;
this.sortId = 1;
}
public void analyzeTempData(WebCadDataReqVO webCadDataReqVO) {
@@ -695,7 +692,6 @@ public class WebCadOrderImportFactory {
.orderId(orderId)
.plateId(plateDO.getId())
.batchId(batchId)
.sortId(sortId++)
.texture(block.getTexture())
.typographicFace(block.getHoleArrange())
.openDoorType(block.getOpenDoorType())
@@ -1708,11 +1704,15 @@ public class WebCadOrderImportFactory {
if (!isLast) {
// 存储完成清理 list
list.clear();
clearPlate();
}
}
}
private void clearPlate(){
plateDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
}
private void orderItemBatchInsertWithinThreshold(List<OrderItemDO> list, boolean isLast) {
// 达到批量的阈值就做一次插入
if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
@@ -1744,11 +1744,15 @@ public class WebCadOrderImportFactory {
if (!isLast) {
// 存储完成清理 list
list.clear();
clearItem();
}
}
}
private void clearItem(){
orderItemDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
}
private void orderPartBatchInsertWithinThreshold(List<OrderPartsDO> list, boolean isLast) {
// 达到批量的阈值就做一次插入
if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
@@ -1795,11 +1799,15 @@ public class WebCadOrderImportFactory {
if (!isLast) {
// 存储完成清理 list
list.clear();
clearPart();
}
}
}
private void clearPart(){
orderPartsDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
}
/**
* 每达到阈值就批量插入一次生产单造型数据和压缩数据
*
@@ -1812,7 +1820,7 @@ public class WebCadOrderImportFactory {
orderInputProcessor.batchAsyncSaveModel(orderModelDOS);
if (!isLast) {
// 存储完成清理 list
orderModelDOS.clear();
orderModelDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
}
}
}
@@ -1941,20 +1949,20 @@ public class WebCadOrderImportFactory {
* 清空所有列表
*/
private void clearAll() {
roomBodyMap.clear();
bodyMap.clear();
orderGroupMap.clear();
materialMap.clear();
processGroupMap.clear();
existRoomIdMap.clear();
orderPartMap.clear();
roomBodyMap = null;
bodyMap = null;
orderGroupMap = null;
materialMap = null;
processGroupMap = null;
existRoomIdMap = null;
orderPartMap = null;
plateDOS.clear();
orderItemDOS.clear();
orderPartsDOS.clear();
orderModelDOS.clear();
rawGoodsDOS.clear();
goodsDOS.clear();
sealEdgeConfigList.clear();
plateDOS = null;
orderItemDOS = null;
orderPartsDOS = null;
orderModelDOS = null;
rawGoodsDOS = null;
goodsDOS = null;
sealEdgeConfigList = null;
}
}