Files
schemaCheck/docs/配置说明.md
dongzi fd5aab5e7f
All checks were successful
序列化结构检查 / serialization-schema-check (push) Has been skipped
feat: 坐标重命名
2026-07-15 11:33:24 +08:00

11 KiB
Raw Blame History

序列化结构检测 — 配置说明

双层配置:工具 jar 内置 default-config.yaml(默认) + 业务仓库 .gitea/config/serialization-schema-check-config.yaml(覆盖)
工具坐标:com.codechecker:serialization-schema-checker:1.0.0
主类:com.codechecker.cache.cli.SerializationSchemaCheckerMain


1. 配置合并机制

jar 内 default-config.yaml工具仓维护
        ↓ 深度合并
业务仓 serialization-schema-check-config.yaml业务仓维护
        ↓
最终生效配置
  • 业务配置仅需写差异项,不必复制全部默认规则
  • 升级 jar 时,默认忽略规则/检测模式自动跟随工具版本演进
  • 业务仓必须存在 --config 指定的配置文件(可为仅含 mode 的最小文件)

1.1 业务仓最小配置示例

# jnpf-java-cloud/.gitea/config/serialization-schema-check-config.yaml
enabled: true
mode: notify

notify:
  enabled: true
  # 推荐直接写完整 Webhook也可用环境变量在流水线注入
  webhook_url: ""

include_modules:
  - jnpf-tenant

流水线通常把 Secret 注入环境或配置文件中的 webhook_url。兼容旧字段:webhook_env(值为 http 开头时当作 URL 使用)。

1.2 工具内置默认配置jar 内 default-config.yaml

redisCheck 仓库维护,随 jar 发布,默认包含:

  • detection.patternsW01~W05JSON 字符串写入 + Template 直写 + Hash
  • detection.read_hints_enabledW06 读侧反序列化类型辅助(默认 true
  • ignore.key_patterns(锁 / 计数器 / token
  • detection.min_confidencemax_field_depth
  • mode: notifyenabled: true

2. 业务仓完整配置示例

# 总开关false 时不执行检测、不发通知、流水线直接通过
enabled: true

# 运行模式
# notify - 仅通知,不阻断流水线
# block  - 检测到结构变更即阻断流水线exit 1
mode: notify

# 是否扫描测试代码(已确认:不扫描)
scan_test_sources: false

# 源码扫描根目录(仅 main不含 test
source_roots:
  - "src/main/java"

# 通知配置
notify:
  enabled: true
  # Webhook 完整 URL优先
  webhook_url: ""
  # 兼容旧字段:值为 http 开头时视为 URL
  # webhook_env: WECOM_ROBOT_WEBHOOK
  # 无变更时是否也发通知(一般 false
  notify_on_clean: false
  # 消息标题前缀
  title_prefix: "[序列化结构变更]"

# 忽略规则
ignore:
  # 忽略的 key 模式glob
  key_patterns:
    - "*:lock"
    - "*:lock:*"
    - "*lock*"
    - "loginCount:*"
    - "Authorization:*"

  # 忽略的文件路径模式
  file_patterns:
    - "**/test/**"

  # 忽略的写入方法(类全名#方法名)
  writer_methods: []

# 检测规则
detection:
  # 启用的写入模式(默认已全部开启)
  patterns:
    - W01   # redisUtil.insert + JSON.toJSONString
    - W02   # redisTemplate.opsForValue().set + JSON.toJSONString
    - W03   # stringRedisTemplate + JsonUtil.getObjectToString
    - W04   # redisTemplate 直写对象
    - W05   # opsForHash().put

  # W06读侧反序列化类型辅助不产生独立告警
  read_hints_enabled: true

  # 类型推断最低置信度,低于此值标记为低置信度提示
  min_confidence: 0.6

  # 字段展开最大深度(防止循环引用死循环)
  max_field_depth: 8

# 人工补充映射(自动推断失败或需精确指定时使用)
manual_mappings:
  - id: tenant-db-content
    writer_method: "jnpf.util.TenantDbContentCacheHelper#cacheSuccess"
    key_pattern: "tenant:db:content:*"
    value_type: "jnpf.util.TenantDbContentCacheHelper.CacheEnvelope"
    description: "租户库信息缓存"

  - id: attendance-base-setting
    writer_method: "jnpf.attendance.service.impl.AttendanceBaseSettingServiceImpl#getStringAttendanceBaseSettingMap"
    key_pattern: "fbt:attendance:base_setting:cache:*"
    value_type: "java.util.Map"
    description: "考勤基础设置缓存Map<String, AttendanceBaseSetting>"

# 抑制规则(已知误报)
suppressions:
  - id: ignore-export-progress
    key_pattern: "file:download:user:progress:*"
    reason: "导出进度缓存,结构变更不影响业务读取"

# 模块过滤(可选,默认扫描全部模块)
include_modules:
  - jnpf-tenant
  - jnpf-ftb
  - jnpf-file
  - fantaibao-data-analysis

# exclude_modules: []

3. 配置项说明

3.1 enabled

总开关。默认 true

行为
true 正常执行检测(再按 mode / notify 行为)
false 跳过检测与通知,流水线 exit 0(与 notify.enabled 无关)

临时关闭时可仅改此项,无需删除 workflow。

3.2 mode

行为
notify 检测到变更 → 发企微 → exit 0
block 检测到任意结构变更 → 发企微 → exit 1

建议上线初期仍使用 mode: notify 观察误报情况,确认稳定后再切换:

mode: block

3.3 notify

字段 类型 默认值 说明
enabled boolean true 是否发企微
webhook_url string "" 企微机器人 Webhook 完整 URL优先
webhook_env string 兼容旧字段;值为 http 开头时当作 URL
notify_on_clean boolean false 无变更时是否通知
title_prefix string [序列化结构变更] 消息标题前缀

3.4 ignore.key_patterns

支持 glob

  • * 匹配单层
  • ** 匹配多层

内置/代码层常见过滤:

  • 分布式锁 key配置 glob + 方法名忽略)
  • 登录计数、session/token
  • 琐碎 value字面量、"1"UUID.randomUUID()
  • 方法:setIfAbsent / increment / delete / expire

3.5 detection.patterns

模式 说明 状态
W01 redisUtil.insert(key, JSON.toJSONString(x), ttl) 已启用
W02 redisTemplate.opsForValue().set(key, JSON.toJSONString(x), ...) 已启用
W03 stringRedisTemplate.opsForValue().set(key, JsonUtil.getObjectToString(x), ...) 已启用
W04 redisTemplate.opsForValue().set(key, obj, ...) 直写对象 已启用Phase 2
W05 redisTemplate.opsForHash().put(key, field, obj) 已启用Phase 2

业务仓可通过只声明子集暂时关闭某些模式,例如仅保留 JSON 写入:

detection:
  patterns: [W01, W02, W03]

3.5.1 detection.read_hints_enabledW06 辅助)

字段 类型 默认 说明
read_hints_enabled boolean true 扫描 parseObject / parseArray / getJsonToBean 等,补强同文件或同 key 写入点的 value 类型
  • 不是写入模式:不会单独因为「多了一处 parse」而告警
  • 能关联到 redis get(key) 时,还可补强 unresolved key
  • 覆盖优先级:manual_mappings > W06 > 写侧 AST

关闭示例:

detection:
  read_hints_enabled: false

3.6 manual_mappings

当自动推断不准确时使用。匹配优先级 高于 自动推断(按 类全名#方法名 覆盖 key 模式与 value 类型)。

字段 必填 说明
id 唯一标识
writer_method 类全名#方法名,精确匹配写入点
key_pattern 精确 key 模式
value_type 强制指定 value 类型
description 备注

3.7 suppressions

用于屏蔽已知可接受的变更:

suppressions:
  - id: my-suppression
    key_pattern: "file:download:user:progress:*"
    change_types:
      - FIELD_ADDED
    reason: "新增字段向后兼容"

3.8 include_modules / exclude_modules

字段 说明
include_modules 非空时仅扫描列出的顶层模块;空表示全仓
exclude_modules 始终排除的顶层模块

顶层模块取路径第一段,例如 jnpf-tenant/jnpf-tenant-biz/src/main/java/...jnpf-tenant


4. 环境变量 / Secret

变量 必填 说明
WECOM_ROBOT_WEBHOOK 视流水线写法 可将 Secret 写入配置中的 webhook_url,或在启动前注入

在 Gitea 仓库 Settings → Secrets 中配置。


5. 企微消息格式

5.1 结构说明

  • 抬头:仓库、分支、提交、提交人、时间(不展示 mode
  • 正文:按 一个 Redis Key 一块,展示位置、类型与前后序列化骨架
  • 超长UTF-8 > 4096 字节)时按 key 拆成多条消息依次发送
  • CI 控制台另打「字段明细」(变更类型 / 位置 / 摘要),企微侧按骨架展示

5.2 字段高亮颜色

变更 企微颜色 Markdown
字段删除(标在旧骨架) 橙色 <font color="warning">…</font>
字段新增 / 包装层(标在新骨架) 绿色 <font color="info">…</font>
路径迁移 旧橙 / 新绿 同上
key 未解析提示 灰色 <font color="comment">key 未解析)</font>

5.3 示例(已解析 key

## [序列化结构变更] jnpf-java-cloud

> **分支**: code/redis_change_detection_v1.0
> **提交**: cedd161c → 67c8a6eb
> **提交人**: dongzi
> **时间**: 2026-07-13 16:54:17

- Key --> `tenant:db:content:*`
  > **位置**: `TenantDbContentCacheHelper#cacheSuccess:92`
  > **类型**: `CacheEnvelope`
  > **value值由** “{"dbName":"","linkList":[{"id":""}]}”
  > **变更为:** “…(仅新增/迁移字段片段带 <font color="info">绿色</font>)…”

实际发送时仅对改动属性片段染色:新增 → info(绿),删除 → warning(橙)。

5.4 示例key 未解析)

- Key --> `req.getKey()` <font color="comment">key 未解析)</font>
  > **位置**: `ClockInXxxService#export:128`
  > **类型**: `List<ClockInExportVo>`
  > **value值由** “{"a":""}”
  > **变更为:** “…新增字段带绿色高亮…”

未解析时按「写入位置 + key 表达式」拆分聚合,避免多个未知 key 串在一起。


6. 推荐上线配置

业务仓默认配置:

enabled: true
mode: notify

notify:
  enabled: true
  webhook_url: ""   # 由流水线写入真实 Webhook

include_modules: []  # 全仓

7. 扩展MQ 消息体检测(方案阶段)

MQRocketMQ + Kafka)消息体 Schema 变更监控方案已单独成文,实现前不要求业务仓增配

详见:MQ序列化结构检测方案.md

届时预计新增:detection.mq_patterns(含 MQ01~MQ-K01~)、detection.mq_read_hints_enabledignore.mq_destinations