# 预存问题 — 当前代码可完善项 **日期**: 2026-05-06 --- ## 可修复: 4 项 (覆盖 ~38,000 错误/天) ### 1. 🔴 P0: addFace 图片为空无限重试 (36,560次) **文件**: `CpImageStoreToolServiceImpl.java` L335-388 **根因**: ```java // L343: 人员不存在时创建空对象 ImgStorePerson imgStorePerson = CollectionUtils.isEmpty(personList) ? new ImgStorePerson() // ← 空person,comparePicture=null : personList.get(0); // L346: 拿到的图片URL为空 extractParam.setImageUrl(imgStorePerson.getComparePicture()); // → 特征提取异常 → L386 日志 "图片为空" ``` **修复**: ```java // 人员不存在时直接返回失败,不继续处理 if (CollectionUtils.isEmpty(personList)) { this.logger.warn("人员不存在 imageId={}", param.getImageId()); return CloudwalkResult.fail("53060434", getMessage("53060434")); } ImgStorePerson imgStorePerson = personList.get(0); if (StringUtils.isBlank(imgStorePerson.getComparePicture())) { this.logger.warn("人员图片为空 personId={} imageId={}", imgStorePerson.getId(), param.getImageId()); return CloudwalkResult.fail("53060434", getMessage("53060434")); } ``` **影响**: 消除 36,560 次错误日志 (占全部错误 45%) --- ### 2. 🟠 P1: addValidateData Redis 锁竞争 (688+322次) **文件**: `CpImageStorePersonValidateManager.java` L102-141, L135-185 **根因**: - `group-person-syn-pool` 线程池并发调用 `addValidateData` - `removeMap`/`addMap` 中多个 entry 竞争同一个 Quartz job 的 Redis 锁 - 688 次 error 集中在同一秒 (2026-02-27 15:14:26) **修复**: ```java // L103: 在 for-loop 之前对 removeMap 按时间戳去重 // 避免多个线程处理相同的 job key for (Map.Entry> entry : dedupedRemoveMap.entrySet()) { // L107: 锁获取失败时不打 ERROR,改为 WARN if (!this.validateJobGroupLock(l, lockValue)) { log.warn("获取job锁失败(可能已被其他线程处理) key={}", l); continue; } // ... 原逻辑 ... } // L185: 同样处理 addMap ``` **影响**: 消除 1,010 次 error 日志 + 减少 Redis 连接竞争 --- ### 3. 🟡 P2: 图片角度识别失败 (35次) **文件**: `ImageEditUtils.java` L140-148 **根因**: Commons Imaging 库解析 TIFF/JPEG 格式时抛异常 **修复**: ```java // L145: 添加更详细的错误日志 + 降级处理 } catch (Exception e) { log.warn("图片角度识别失败, 降级为0度: {}", e.getMessage()); return 0; // 降级为不旋转,而不是抛出异常 } ``` **影响**: 消除 35 次 error 日志 + 提高图片处理容错性 --- ### 4. 🟡 P2: device updatePerson 空指针 (4,749次) **文件**: `CpOrgDeviceKitController.java` L160 (web 模块) **根因**: `cause:` 后为空 — 下游返回 null **修复**: ```java } catch (Exception e) { log.error("device updatePerson error deviceCode={} cause={}", param.getDeviceId(), e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(), e); // 打印完整 stack trace return CloudwalkResult.fail("53060411", getMessage("53060411")); } ``` **影响**: 可追踪 4,749 次失败的真实原因 --- ## 不可修复: 5 项 (下游/基础设施) | 错误 | 原因 | |------|------| | AggDeviceImageStoreFeignClient failed (36K) | cwos-portal 服务不可达 — 运维排查 | | AtomicDeviceFeignClient failed (368) | 设备管理服务不可达 | | VehicleFeignClient failed (68) | 车牌服务不可达 | | ElevatorFeignClient failed (15) | 电梯服务不可达 | | MySQL connection lost (13) | 数据库连接池配置 | --- ## 实施优先级 | 顺序 | 修复项 | 文件 | 消除错误数 | 预估行数 | |------|--------|------|-----------|---------| | 1 | addFace 空图片 | CpImageStoreToolServiceImpl.java | 36,560 | +8行 | | 2 | Redis 锁竞争 | CpImageStorePersonValidateManager.java | 1,010 | +5行 | | 3 | device updatePerson | CpOrgDeviceKitController.java | 4,749 | +3行 | | 4 | 图片角度识别 | ImageEditUtils.java | 35 | +2行 | **总计**: 4 文件, ~18 行代码, 消除 ~42,354 错误/天 (53%)