Files
starRiverProperty/docs/superpowers/data/2026-05-06-component-org-production-error-fix-plan.md
T
反编译工作区 25db029859 feat: 租户访客策略 SQL、访客邀约验证包、component-org 与发布脚本
- docs/sql: organization_* 与 tenant_* 访客楼层策略脚本
- docs/testing: 访客邀约页初始化验证、pack 脚本与 README(忽略 dist/__pycache__)
- maven-ninca-common-component-organization: CpImageStoreServiceImpl、starter、run-verify、releases 脚本与 javap 审计 JSON
- docs/superpowers: component-org 生产问题修复计划
- scripts/test-env/prepare-db.sh 更新

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-06 22:00:16 +08:00

4.1 KiB
Raw Blame History

预存问题 — 当前代码可完善项

日期: 2026-05-06


可修复: 4 项 (覆盖 ~38,000 错误/天)

1. 🔴 P0: addFace 图片为空无限重试 (36,560次)

文件: CpImageStoreToolServiceImpl.java L335-388

根因:

// L343: 人员不存在时创建空对象
ImgStorePerson imgStorePerson = CollectionUtils.isEmpty(personList) 
    ? new ImgStorePerson()  // ← 空personcomparePicture=null
    : personList.get(0);
// L346: 拿到的图片URL为空
extractParam.setImageUrl(imgStorePerson.getComparePicture());
// → 特征提取异常 → L386 日志 "图片为空"

修复:

// 人员不存在时直接返回失败,不继续处理
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)

修复:

// L103: 在 for-loop 之前对 removeMap 按时间戳去重
// 避免多个线程处理相同的 job key
for (Map.Entry<Long, Set<SyncPersonLocal>> 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 格式时抛异常

修复:

// 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

修复:

} 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%)