9.8 KiB
9.8 KiB
缓存序列化结构检测 — 配置说明
双层配置:工具 jar 内置
default-config.yaml(默认) + 业务仓库.gitea/config/cache-schema-check-config.yaml(覆盖)
工具坐标:com.codechecker:cache-schema-checker:1.0.0
主类:com.codechecker.cache.cli.CacheSchemaCheckerMain
1. 配置合并机制
jar 内 default-config.yaml(工具仓维护)
↓ 深度合并
业务仓 cache-schema-check-config.yaml(业务仓维护)
↓
最终生效配置
- 业务配置仅需写差异项,不必复制全部默认规则
- 升级 jar 时,默认忽略规则/检测模式自动跟随工具版本演进
- 业务仓必须存在
--config指定的配置文件(可为仅含mode的最小文件)
1.1 业务仓最小配置示例
# jnpf-java-cloud/.gitea/config/cache-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.patterns:W01~W05(JSON 字符串写入 + Template 直写 + Hash)ignore.key_patterns(锁 / 计数器 / token)detection.min_confidence、max_field_depthmode: notify、enabled: 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
# 类型推断最低置信度,低于此值仅输出 P2 提示
min_confidence: 0.6
# 字段展开最大深度(防止循环引用死循环)
max_field_depth: 8
# 严重级别覆盖(可选)
severity_overrides:
FIELD_ADDED: P1
WRITE_POINT_ADDED: P2
# 人工补充映射(自动推断失败或需精确指定时使用)
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.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 / P0P1P2 汇总)
- 正文:按 一个 Redis Key 一块,展示位置、类型与前后序列化骨架
- 超长(UTF-8 > 4096 字节)时按 key 拆成多条消息依次发送
- CI 控制台另打「字段明细」(含 P0/P1/P2),企微侧不分级别
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. 推荐上线配置
6.1 观察期(第 1 周)
业务仓默认配置:
enabled: true
mode: notify
notify:
enabled: true
webhook_url: "" # 由流水线写入真实 Webhook
include_modules:
- jnpf-tenant
观察满 1 周、确认误报可接受后,手动切换:
mode: block
include_modules: [] # 扩至全仓
6.2 全量启用(观察期结束后)
enabled: true
mode: block
include_modules: [] # 空表示全部模块
detection:
patterns: [W01, W02, W03, W04, W05]