|
@@ -16,6 +16,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 处理考试过程中抓拍照片比对任务
|
|
@@ -42,7 +45,7 @@ public class FaceVerifyJobHandler {
|
|
|
shardIndex, batchSize, param.getMaxErrorNum(), true);
|
|
|
|
|
|
if (CollectionUtils.isEmpty(todoExamRecordDataIds)) {
|
|
|
- // 未取到时,再取一次“不区分状态”的考试记录ID集合
|
|
|
+ // 未取到时,再按常规取一次考试记录ID集合
|
|
|
todoExamRecordDataIds = examCaptureQueueService.findQueuesGroupByExamRecordDataId(shardTotal,
|
|
|
shardIndex, batchSize, param.getMaxErrorNum(), false);
|
|
|
|
|
@@ -52,32 +55,34 @@ public class FaceVerifyJobHandler {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- List<ExamCaptureQueueEntity> queues = examCaptureQueueRepo.findByExamRecordDataIdIn(todoExamRecordDataIds);
|
|
|
- if (CollectionUtils.isEmpty(queues)) {
|
|
|
+ List<ExamCaptureQueueEntity> todoQueues = examCaptureQueueRepo.findByExamRecordDataIdIn(todoExamRecordDataIds);
|
|
|
+ if (CollectionUtils.isEmpty(todoQueues)) {
|
|
|
return;
|
|
|
}
|
|
|
- log.warn("分片任务_FACE_{}_{} examRecordDataIdSize:{} queueSize:{}", shardTotal, shardIndex, todoExamRecordDataIds.size(), queues.size());
|
|
|
|
|
|
- for (Long examRecordDataId : todoExamRecordDataIds) {
|
|
|
+ log.warn("分片任务_FACE_{}_{} examRecordDataIdSize:{} queueSize:{}", shardTotal, shardIndex, todoExamRecordDataIds.size(), todoQueues.size());
|
|
|
+ Map<Long, List<ExamCaptureQueueEntity>> maps = todoQueues.stream().collect(Collectors.groupingBy(ExamCaptureQueueEntity::getExamRecordDataId));
|
|
|
+
|
|
|
+ for (Map.Entry<Long, List<ExamCaptureQueueEntity>> entry : maps.entrySet()) {
|
|
|
+ Long examRecordDataId = entry.getKey();
|
|
|
final String lockKey = CacheConstants.LOCK_FACE_COMPARE + examRecordDataId;
|
|
|
+
|
|
|
try {
|
|
|
SequenceLockHelper.getLockSimple(lockKey);
|
|
|
|
|
|
- // 处理未比对的抓拍照片
|
|
|
- examCaptureQueueService.handlerExamCaptureQueuesByExamRecordDataId(examRecordDataId, param);
|
|
|
+ // 分别按“考试记录ID”集中处理未比对的抓拍照片记录(每个考试记录ID下通常只有几条待处理记录)
|
|
|
+ examCaptureQueueService.handlerExamCaptureQueuesByExamRecordDataId(examRecordDataId, entry.getValue(), param);
|
|
|
} catch (Exception e) {
|
|
|
if (e instanceof InterruptedException) {
|
|
|
// 若线程终止,则抛出交由任务调度中心处理
|
|
|
- log.warn("当前人脸比对任务线程被终止!examRecordDataId:{}, error:{}", examRecordDataId,
|
|
|
- e.getMessage());
|
|
|
+ log.warn("当前人脸比对任务线程被终止!examRecordDataId:{}, error:{}", examRecordDataId, e.getMessage());
|
|
|
throw e;
|
|
|
} else if (e instanceof SequenceLockException) {
|
|
|
// 若锁问题,下次会继续执行
|
|
|
log.warn("当前人脸比对任务获取锁失败!examRecordDataId:{}, redisKey:{}", examRecordDataId, lockKey);
|
|
|
} else {
|
|
|
// 若异常,下次会继续执行(需要排查原因)
|
|
|
- log.error("当前人脸比对任务处理失败!examRecordDataId:{}, error:{}", examRecordDataId,
|
|
|
- e.getMessage());
|
|
|
+ log.error("当前人脸比对任务处理失败!examRecordDataId:{}, error:{}", examRecordDataId, e.getMessage());
|
|
|
}
|
|
|
} finally {
|
|
|
SequenceLockHelper.releaseLockSimple(lockKey);
|
|
@@ -95,7 +100,8 @@ public class FaceVerifyJobHandler {
|
|
|
|
|
|
JsonNode maxThreadNum = jsonParams.get("maxThreadNum");
|
|
|
if (maxThreadNum != null) {
|
|
|
- param.setMaxThreadNum(maxThreadNum.asInt(3));
|
|
|
+ // 最大数不超过20
|
|
|
+ param.setMaxThreadNum(Math.min(maxThreadNum.asInt(3), 20));
|
|
|
}
|
|
|
|
|
|
JsonNode maxErrorNum = jsonParams.get("maxErrorNum");
|