Files
starRiverProperty/docs/superpowers/specs/2026-05-10-component-org-log-analysis.md
T

16 KiB
Raw Blame History

component-organization.info.log 全量分析 & 策略频繁调用根因分析

日期: 2026-05-10 日志范围: 12:41:32 ~ 13:18:38 (37 分钟) 分支: feature/guangfa-28f-hardcoded 数据库: 10.0.22.103 / cloudwalk / component-organization


一、日志概览

文件: logs/component-organization.info.log
大小: 26MB
行数: 106,372
TraceId: 9,848 个
服务端口: 17016

日志构成

████████████████████████████░░░░░ 84.2%  设备同步 (89,531 行)
██████████░░░░░░░░░░░░░░░░░░░░░░ 29.9%  WARN (31,800 行)
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  0.06% 用户业务 detail() 调用 (64 行)
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  0.02%  ERROR (20 行)
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  0.01%  POLICY 命中 (12 行)

二、服务启动时间线

12:41:32  首个请求到达(device updatePerson
12:41:42  Quartz 调度器启动
12:42:07  Hystrix 初始化完成
12:44:07  jasypt 加密引导
12:44:09  Redis Lua 脚本 Bean 覆盖(9 个)
12:44:27  Controller 映射注册 /component/person/listPerson
12:46:27  首个业务 detail() 调用(距启动 ~5 分钟)
13:18:38  最后一条日志(图库同步失败 WARN)

三、业务调用完整时间线(36 次 detail 调用)

3.1 按调用方来源分类

POST /component/person/detail 被以下 7 个调用方 消费:

# 调用方 代码位置 调用场景 是否需要策略
1 前端访客邀约页 通过 PersonController.detail() 初始化可选择楼层 需要
2 前端人员管理 通过 PersonController.detail() 人员详情查看 不需要
3 elevator addVisitor UC-01 PersonRuleServiceImpl:175 一键派梯,需要 floorList 需要
4 elevator addVisitor UC-02 PersonRuleServiceImpl:175 仅校验被访人存在 不需要(不用 floorList)
5 CRK 访客注册 VisitorRegisterServiceImpl:330,648 访客登记 需要
6 CRK 门禁识别记录 AcsRecogRecordServiceImpl:86 识别记录,仅需人员信息 不需要
7 电梯设备/记录 AcsElevatorDeviceServiceImpl 设备同步 不需要

3.2 日志中的调用时序

12:46:27  detail personId=1099676120751034368 [MFG鼎鸿/613]          4 zones  ✗ 未命中
12:46:36  detail personId=833276118323793920  [大地保险/办公室]        3 zones  ✗ 未命中
12:48:44  detail personId=730473849711333376  [行政人事部/陕西巨丰]      5 zones  ✗ 未命中
12:48:50  detail personId=783987999653621760  [陕西巨丰/业务部]         2 zones  ✗ 未命中
12:49:11  detail personId=783987999653621760  [同一人 21秒后再查]       2 zones  ✗ 未命中
12:51:22  detail personId=1032218423083470848 陈晶丽 [外包+物管]       38 zones ★ 命中 → 6F
12:53:31  detail personId=903269751508242432  [陕西巨丰/业务部]         2 zones  ✗ 未命中
12:56:13  detail personId=1087053273767612416 [612/MFG鼎鸿]            4 zones  ✗ 未命中
12:56:25  detail personId=1071436837510660096 [金辉华集团/工程中心]      2 zones  ✗ 未命中
12:56:56  detail personId=1087053273767612416 [同一人 43秒后再查]       4 zones  ✗ 未命中
12:58:18  detail personId=1028610903966322688 [投资助理/陕西巨丰]       2 zones  ✗ 未命中
12:59:55  detail personId=805732141303721984  刘光林 [厨房+物管]        5 zones  ★ 命中 → 6F
12:59:59  detail personId=805732141303721984  [同一人 4秒后再查]        5 zones  ★ 命中 → 6F
13:00:14  detail personId=1105585180195930112 [仅 1 zone]             1 zone   (无策略检查)
13:01:42  detail personId=775326439246499840  [陕西巨丰/业务部]         2 zones  ✗ 未命中
13:02:20  detail personId=992819015204597760  雷恒豫 [外包+物管]       38 zones ★ 命中 → 6F
13:02:24  detail personId=901059320052314112  [财务/陕西巨丰]           2 zones  ✗ 未命中
13:02:26  detail personId=1018452759471689728 [新媒体/陕西巨丰]         4 zones  ✗ 未命中
13:03:06  detail personId=1032604140250959872 冯水英 [环境部+物管]      38 zones ★ 命中 → 6F
13:03:08  detail personId=964199538912989184  戚浩 [外包+物管]         38 zones ★ 命中 → 6F
13:03:25  detail personId=721734719120691200  覃永杰 [保安部+物管]      31 zones ★ 命中 → 6F
13:03:29  detail personId=721734719120691200  [4秒后再查]              31 zones ★ 命中 → 6F  ⚠️
13:03:33  detail personId=721734719120691200  [又4秒后再查]             31 zones ★ 命中 → 6F  ⚠️
13:03:33  detail personId=770218949916094464  [陕西巨丰/业务部]         2 zones  ✗ 未命中
13:03:44  detail personId=721734719120691200  [第4次,11秒后再查]        31 zones ★ 命中 → 6F  ⚠️
13:04:09  detail personId=957214640516231168  [新媒体/陕西巨丰]         4 zones  ✗ 未命中
13:04:41  detail personId=906237696010194944  [陕西巨丰/大客户部]        2 zones  ✗ 未命中
13:05:03  detail personId=771809951973847040  [新媒体/陕西巨丰]         4 zones  ✗ 未命中
13:06:13  detail personId=1030066143429201920 [新媒体/陕西巨丰]         6 zones  ✗ 未命中
13:07:56  detail personId=770218949916094464  [陕西巨丰/业务部]         2 zones  ✗ 未命中
13:09:20  detail personId=1105554183521812480 [仅 1 zone]             1 zone   (无策略检查)
13:10:28  detail personId=1101592364922802176 [MFG鼎鸿/613]            4 zones  ✗ 未命中
13:13:41  detail personId=605578568533016576  [大地保险]               3 zones  ✗ 未命中
13:13:54  detail personId=605578568533016576  [13秒后再查]              3 zones  ✗ 未命中
13:13:54  detail personId=992819015204597760  雷恒豫 [外包+物管]       38 zones ★ 命中 → 6F
13:17:25  detail personId=1079804406034599936 [最后一条]               4 zones  (无策略检查)

3.3 高频重复查询分析

覃永杰 (721734719120691200): 19秒内查询 4 次
  13:03:25 → 13:03:29 (4秒间隔) → 13:03:33 (4秒间隔) → 13:03:44 (11秒间隔)
  判断: 前端批量操作(连续打开多人详情)或页面轮询

刘光林 (805732141303721984): 4秒内查询 2 次
  12:59:55 → 12:59:59
  判断: addVisitor 阶段1 + 前端详情页并发请求

雷恒豫 (992819015204597760): 12分钟内查询 2 次
  13:02:20 → 13:13:54
  判断: 两次独立操作

四、策略频繁调用的根因分析

4.1 问题表述

用户原意: 租户访客楼层策略(TenantVisitorFloorPolicyService)只应在「访客邀约初始化页面」触发,用于确定被访人的可选楼层列表。

实际情况: 策略在 36 次 detail() 调用 中被触发了 24 次(12 次额外命中做了楼层替换),但其中只有部分来自访客邀约场景。

4.2 根因:detail() 是多消费者通用 API,策略代码无条件嵌入

                     POST /component/person/detail
                              │
                              ▼
              ┌───────────────────────────────┐
              │  ImgPersonServiceImpl.detail() │
              │  L670-672:                     │
              │  tenantVisitorFloorPolicy      │
              │  Service.replacementZoneIds    │
              │  IfPolicyActive(orgIds)  ← 无条件触发!
              └───────────────────────────────┘
                              │
          ┌───────────────────┼───────────────────┐
          │                   │                   │
    访客邀约页 ✅         人员管理 ❌         addVisitor
    (需要策略)           (不需要)            UC-02 ❌
                                         (不消费 floorList)

4.3 所有 detail() 调用方一览

personService.detail() 的 Feign 消费者:

1. PersonController.detail()           ← 前端 HTTP 入口
   ├─ 访客邀约页初始化                  ✅ 策略必需
   └─ 人员管理/详情查看                 ❌ 策略无意义(但无法区分)

2. PersonRuleServiceImpl.addVisitor()   ← 电梯侧
   ├─ UC-01(一键派梯)                ✅ 需要 floorList
   └─ UC-02(调用方指定楼层)           ❌ floorList 不被消费(L193 直接取 param.floorIds

3. VisitorRegisterServiceImpl           ← CRK 访客
   ├─ L330 访客登记                    ✅ 可能涉及楼层选择
   └─ L648 访客登记                    ✅ 同上

4. AcsRecogRecordServiceImpl:86        ← CRK 门禁识别
   └─ 仅需人员信息                      ❌ 完全不涉及楼层

4.4 为什么设计如此

设计文档 2026-05-06-tenant-visitor-policy-organization-implementation.md 明确规定:

floorList 唯一主路径:获取 PersonResult.floorList必须调用 PersonService.detail 业务约定:凡调用方需消费「被访人可派梯/可邀约访问的楼层集合」,必须走 PersonService.detail

这一设计将 detail() 作为 floorList 的权威来源,策略替代自然应在 detail() 内完成。但设计未区分「需要 floorList 的调用方」和「仅需人员信息的调用方」——detail() 本就同时承担这两种职责。

4.5 策略命中统计

目标 orgId 组织名 命中次数 限制楼层 备注
f216235e... 星中心物业管理公司 12 6F 物业内部人员被查询
488b8ad0... [28-38F]广发基金 0 28F 日志期间无人查询广发人员

24 次未命中 的 detail() 调用中,大部分是陕西巨丰投资 (a5585cb) 的人员——该组织无策略配置,但仍然触发了 tenant_visitor_floor_policy 表的 SELECT 查询(一次 DB 查询 + 空结果集)。

4.6 性能影响评估

单次 detail() 调用链路:
  
  DB: cw_is_person                          (必选)
  DB: cw_is_person_organization_ref         (必选)  
  DB: cw_is_person_label_ref                (必选)
  Feign: elevatorFeignClient.listByImageId  (必选, 跨服务调用)
  DB: tenant_visitor_floor_policy           (★ 策略查询, 每次 1 次 SELECT)
      WHERE org_id=? AND enabled=1 LIMIT 1
      → 对每个 orgId 执行,命中即停止遍历
  • 策略查询是基于 org_id 的索引查询(idx_org_enabled),单次耗时 < 5ms
  • 当前日志中 1次/分钟 的频率无性能问题
  • 但若 detail() 被大量并发调用(如批量操作、定时任务),会产生 N×orgCount 次 DB 查询

五、异常与风险

5.1 设备同步 WARN (31,800 条)

"查询设备[xxx]失败" (DevicePersonSyncManager:164)
  
TOP 5 失败设备:
  cbbd0da12a9247409cc272e1c365698f  180 次
  508d126a19554746a46931afcc5ec9e3  180 次
  ca9d9689c8fe4ccf89eba82a9c9df4b4  120 次
  f4765e409ffd4705a2639eb41c5251c7  115 次
  7a4b5acc463d465ba4550db4939dac19  105 次

原因: 设备侧有注册,组织库中无对应设备 → 每次同步周期都触发查询失败
影响: 日志膨胀(84% 为设备同步日志),掩盖真实业务问题
建议: 清理数据库中不存在的设备记录,或对已知失败设备做静默处理

5.2 Feign 调用失败 (11 次 ERROR)

"call AggDeviceImageStoreFeignClient sync device imageStore failed"
(Hystrix fallback, 分布在 12:49 ~ 13:18)

间隔: 约 1-2 分钟一次
原因: cwos-portal 服务不可达或超时
影响: 图库同步中断,但不影响人员查询

5.3 图库添加人脸失败 (5 次 ERROR)

"图库[c8c67225]添加人脸[1690239736450007040]异常"
"图库[7a83a5d2]添加人脸[1611164976657559552]异常" × 4

集中在 13:06~13:07,为批量操作失败

六、策略优化建议

方案 A:添加调用上下文标志(推荐,最小变更)

DetailImgPersonParamCloudwalkCallContext 中添加 skipFloorPolicy 字段:

// ImgPersonServiceImpl.detail() L670 修改为:
if (!Boolean.TRUE.equals(param.getSkipFloorPolicy())) {
    Optional<List<String>> replacementFloors =
        this.tenantVisitorFloorPolicyService
            .replacementZoneIdsIfPolicyActive(result.getOrganizationIds());
    // ... 现有替换逻辑
}

优点: 调用方显式控制,不破坏现有契约 缺点: 需要所有「不需要策略」的调用方传参(addVisitor UC-02、门禁识别、人员管理等)

方案 B:策略仅在 isVisitor 场景触发

// 仅在访客相关场景触发策略
if (Boolean.TRUE.equals(param.getIsVisitor())) {
    // 策略检查
}

优点: 改动最小,一行条件判断 缺点: isVisitor 可能不是当前 detail() 的必有参数

方案 C:保持现状(设计意图)

按照设计文档,detail() 是 floorList 的权威来源,策略嵌入是有意为之。当前 ~1次/分钟 的调用频率下,额外的 DB 查询成本可忽略。

优点: 零改动 缺点: 语义不精确,所有 detail() 消费者都触发策略查询


七、数据库查询结果附录

7.1 策略表全量

SELECT p.id, p.org_id, o.NAME, p.allow_zone_ids, p.remark
FROM tenant_visitor_floor_policy p
LEFT JOIN cw_is_organization o ON p.org_id = o.ID
WHERE p.enabled=1;
policyId org_name allow_zone_ids 限制楼层
pm_6f_vstr_policy_006 星中心物管公司 ["605560541473144832"] 6F
pm_6f_vstr_policy_001 星河湾物业管理有限公司 ["605560541473144832"] 6F
pm_6f_vstr_policy_005 星中心物业服务中心 ["605560541473144832"] 6F
pm_6f_vstr_policy_003 星河湾物管公司 ["605560541473144832"] 6F
pm_6f_vstr_policy_007 物业管理总部 ["605560541473144832"] 6F
pm_6f_vstr_policy_004 星中心物业管理公司 ["605560541473144832"] 6F ← 日志命中
pm_6f_vstr_policy_002 星河湾物业管理公司 ["605560541473144832"] 6F
gf_vstr_policy_guangfa_fund_001x [28-38F]广发基金管理有限公司 ["605560545117995008"] 28F
demo_vstr_policy_001 演示公司 ["605560545117995008"] 28F

7.2 楼层编码对照

zone_id=605560540432957440  code=0x01 →  1F (首层)
zone_id=605560541473144832  code=0x06 →  6F ★ 物业策略目标
zone_id=605560545117995008  code=0x1C → 28F ★ 广发基金策略目标

7.3 关键组织节点

f216235e54ca42bfa0379e69b3754aff = 星中心物业管理公司  (PARENT_ORG)
  ├── 348328d755624b3491cd307a3109f36a = 星中心物管公司
  ├── b39c54d13fe94abe84bfa8d527db4392 = 星中心保安部
  ├── f113340e671648338eb83fc643cfa94d = 星中心环境管理部
  │     └── 8498d4a56f07494ca604789d23fc18f6 = 星中心环境部外包人员
  └── df573ae4b98f4be092d524b760bd5c40 = 星景厨房

a5585cb03764490c915ee807aaa13ef3 = 陕西巨丰投资资讯有限责任公司广州分公司
  ├── b3b5fe629baf45b29a1eb6ed8e7126d8 = 业务部
  ├── 363742435e3f4dc1b4626819e8637de2 = 行政人事部
  ├── 4758f34c67364c4c8f6f6c8eb9a4af13 = 新媒体
  ├── 480bd6c8b49b49568f7a5ee07331a084 = 投资助理
  ├── 768aa5ef294d4fdc979e1c5a37cb87e7 = 财务/数据/推广
  └── e84e681fa6c8463c90f70082cd4bed77 = 大客户服务部

488b8ad049bb43408a6fbcc50bcb89ac = [28-38F]广发基金管理有限公司  (有策略但未被查询)

八、总结

  1. 日志主体是设备同步(84.2%),用户业务调用仅占 0.06%
  2. 策略调用频率: 36 次/37 分钟 ≈ 1 次/分钟,频率不高但覆盖所有 detail() 调用方
  3. 根因: detail() 是 floorList 的权威来源(设计意图),策略嵌入是有意为之;但 detail() 被 7+ 个不同调用方消费,其中仅 3 个需要策略
  4. 是否可以优化: 可以,但需要改动调用方契约(添加 skip 标志)或在 detail() 内根据业务特征判断。当前频率下保持现状是可接受的
  5. 31,800 条 WARN: 设备同步失败是主要噪音源,建议清理不存在设备的记录