You've already forked FrameTour-BE
feat(puzzle): 使用虚拟线程优化拼图模板批量生成性能
- 将原有的串行模板生成逻辑改为并行处理 - 使用虚拟线程池提升高并发场景下的执行效率 - 通过 CompletableFuture 异步执行每个模板的生成任务 - 保留原有日志记录和异常处理机制 - 统计成功与失败数量并输出汇总日志
This commit is contained in:
@@ -74,22 +74,31 @@ public class PuzzleGenerationOrchestrator {
|
||||
// 3. 准备公共动态数据
|
||||
Map<String, String> baseDynamicData = buildBaseDynamicData(faceId, faceUrl, scenicBasic);
|
||||
|
||||
// 4. 遍历所有模板,逐个生成
|
||||
int successCount = 0;
|
||||
int failCount = 0;
|
||||
for (PuzzleTemplateDTO template : templateList) {
|
||||
try {
|
||||
generateSingleTemplate(scenicId, faceId, memberId, template, baseDynamicData);
|
||||
successCount++;
|
||||
} catch (Exception e) {
|
||||
log.error("拼图生成失败: scenicId={}, templateCode={}, templateName={}",
|
||||
scenicId, template.getCode(), template.getName(), e);
|
||||
failCount++;
|
||||
}
|
||||
// 4. 使用虚拟线程池并行生成所有模板
|
||||
java.util.concurrent.atomic.AtomicInteger successCount = new java.util.concurrent.atomic.AtomicInteger(0);
|
||||
java.util.concurrent.atomic.AtomicInteger failCount = new java.util.concurrent.atomic.AtomicInteger(0);
|
||||
|
||||
try (java.util.concurrent.ExecutorService executor = java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor()) {
|
||||
// 为每个模板创建一个异步任务
|
||||
List<java.util.concurrent.CompletableFuture<Void>> futures = templateList.stream()
|
||||
.map(template -> java.util.concurrent.CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
generateSingleTemplate(scenicId, faceId, memberId, template, baseDynamicData);
|
||||
successCount.incrementAndGet();
|
||||
} catch (Exception e) {
|
||||
log.error("拼图生成失败: scenicId={}, templateCode={}, templateName={}",
|
||||
scenicId, template.getCode(), template.getName(), e);
|
||||
failCount.incrementAndGet();
|
||||
}
|
||||
}, executor))
|
||||
.toList();
|
||||
|
||||
// 等待所有任务完成
|
||||
java.util.concurrent.CompletableFuture.allOf(futures.toArray(new java.util.concurrent.CompletableFuture[0])).join();
|
||||
}
|
||||
|
||||
log.info("景区拼图模板批量生成完成: scenicId={}, 总数={}, 成功={}, 失败={}",
|
||||
scenicId, templateList.size(), successCount, failCount);
|
||||
scenicId, templateList.size(), successCount.get(), failCount.get());
|
||||
|
||||
} catch (Exception e) {
|
||||
// 异步任务失败不影响主流程,仅记录日志
|
||||
|
||||
@@ -390,42 +390,51 @@ public class FaceMatchingOrchestrator {
|
||||
baseDynamicData.put("scenicText", scenicBasic.getName());
|
||||
baseDynamicData.put("dateStr", DateUtil.format(new Date(), "yyyy.MM.dd"));
|
||||
|
||||
// 遍历所有模板,逐个生成
|
||||
int successCount = 0;
|
||||
int failCount = 0;
|
||||
for (PuzzleTemplateDTO template : templateList) {
|
||||
try {
|
||||
log.info("开始生成拼图: scenicId={}, templateCode={}, templateName={}",
|
||||
scenicId, template.getCode(), template.getName());
|
||||
// 使用虚拟线程池并行生成所有模板
|
||||
java.util.concurrent.atomic.AtomicInteger successCount = new java.util.concurrent.atomic.AtomicInteger(0);
|
||||
java.util.concurrent.atomic.AtomicInteger failCount = new java.util.concurrent.atomic.AtomicInteger(0);
|
||||
|
||||
// 构建生成请求
|
||||
PuzzleGenerateRequest generateRequest = new PuzzleGenerateRequest();
|
||||
generateRequest.setScenicId(scenicId);
|
||||
generateRequest.setUserId(memberId);
|
||||
generateRequest.setFaceId(faceId);
|
||||
generateRequest.setBusinessType("face_matching");
|
||||
generateRequest.setTemplateCode(template.getCode());
|
||||
generateRequest.setOutputFormat("PNG");
|
||||
generateRequest.setQuality(90);
|
||||
generateRequest.setDynamicData(new HashMap<>(baseDynamicData));
|
||||
generateRequest.setRequireRuleMatch(true);
|
||||
try (java.util.concurrent.ExecutorService executor = java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor()) {
|
||||
// 为每个模板创建一个异步任务
|
||||
List<java.util.concurrent.CompletableFuture<Void>> futures = templateList.stream()
|
||||
.map(template -> java.util.concurrent.CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
log.info("开始生成拼图: scenicId={}, templateCode={}, templateName={}",
|
||||
scenicId, template.getCode(), template.getName());
|
||||
|
||||
// 调用拼图生成服务
|
||||
PuzzleGenerateResponse response = puzzleGenerateService.generate(generateRequest);
|
||||
// 构建生成请求
|
||||
PuzzleGenerateRequest generateRequest = new PuzzleGenerateRequest();
|
||||
generateRequest.setScenicId(scenicId);
|
||||
generateRequest.setUserId(memberId);
|
||||
generateRequest.setFaceId(faceId);
|
||||
generateRequest.setBusinessType("face_matching");
|
||||
generateRequest.setTemplateCode(template.getCode());
|
||||
generateRequest.setOutputFormat("PNG");
|
||||
generateRequest.setQuality(90);
|
||||
generateRequest.setDynamicData(new HashMap<>(baseDynamicData));
|
||||
generateRequest.setRequireRuleMatch(true);
|
||||
|
||||
log.info("拼图生成成功: scenicId={}, templateCode={}, imageUrl={}",
|
||||
scenicId, template.getCode(), response.getImageUrl());
|
||||
successCount++;
|
||||
// 调用拼图生成服务
|
||||
PuzzleGenerateResponse response = puzzleGenerateService.generate(generateRequest);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("拼图生成失败: scenicId={}, templateCode={}, templateName={}",
|
||||
scenicId, template.getCode(), template.getName(), e);
|
||||
failCount++;
|
||||
}
|
||||
log.info("拼图生成成功: scenicId={}, templateCode={}, imageUrl={}",
|
||||
scenicId, template.getCode(), response.getImageUrl());
|
||||
successCount.incrementAndGet();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("拼图生成失败: scenicId={}, templateCode={}, templateName={}",
|
||||
scenicId, template.getCode(), template.getName(), e);
|
||||
failCount.incrementAndGet();
|
||||
}
|
||||
}, executor))
|
||||
.toList();
|
||||
|
||||
// 等待所有任务完成
|
||||
java.util.concurrent.CompletableFuture.allOf(futures.toArray(new java.util.concurrent.CompletableFuture[0])).join();
|
||||
}
|
||||
|
||||
log.info("景区拼图模板批量生成完成: scenicId={}, 总数={}, 成功={}, 失败={}",
|
||||
scenicId, templateList.size(), successCount, failCount);
|
||||
log.info("景区拼图模板批量生成完成: scenicId={}, 总数={}, 成功={}, 失败={}",
|
||||
scenicId, templateList.size(), successCount.get(), failCount.get());
|
||||
|
||||
} catch (Exception e) {
|
||||
// 异步任务失败不影响主流程,仅记录日志
|
||||
|
||||
Reference in New Issue
Block a user