Files
schemaCheck/docs/配置说明.md
2026-07-14 17:11:58 +08:00

350 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 缓存序列化结构检测 — 配置说明
> **双层配置**:工具 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. 配置合并机制
```text
jar 内 default-config.yaml工具仓维护
↓ 深度合并
业务仓 cache-schema-check-config.yaml业务仓维护
最终生效配置
```
- 业务配置**仅需写差异项**,不必复制全部默认规则
- 升级 jar 时,默认忽略规则/检测模式自动跟随工具版本演进
- 业务仓必须存在 `--config` 指定的配置文件(可为仅含 `mode` 的最小文件)
### 1.1 业务仓最小配置示例
```yaml
# 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_depth`
- `mode: notify``enabled: true`
---
## 2. 业务仓完整配置示例
```yaml
# 总开关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` 观察误报情况,确认稳定后再切换:
```yaml
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 写入:
```yaml
detection:
patterns: [W01, W02, W03]
```
### 3.6 manual_mappings
当自动推断不准确时使用。匹配优先级 **高于** 自动推断(按 `类全名#方法名` 覆盖 key 模式与 value 类型)。
| 字段 | 必填 | 说明 |
|------|------|------|
| `id` | 是 | 唯一标识 |
| `writer_method` | 否 | `类全名#方法名`,精确匹配写入点 |
| `key_pattern` | 否 | 精确 key 模式 |
| `value_type` | 否 | 强制指定 value 类型 |
| `description` | 否 | 备注 |
### 3.7 suppressions
用于屏蔽已知可接受的变更:
```yaml
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
```markdown
## [缓存结构变更] 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 未解析)
```markdown
- Key --> `req.getKey()` <font color="comment">key 未解析)</font>
> **位置**: `ClockInXxxService#export:128`
> **类型**: `List<ClockInExportVo>`
> **value值由** “{"a":""}”
> **变更为:** “…新增字段带绿色高亮…”
```
未解析时按「写入位置 + key 表达式」拆分聚合,避免多个未知 key 串在一起。
---
## 6. 推荐上线配置
### 6.1 观察期(第 1 周)
业务仓默认配置:
```yaml
enabled: true
mode: notify
notify:
enabled: true
webhook_url: "" # 由流水线写入真实 Webhook
include_modules:
- jnpf-tenant
```
观察满 1 周、确认误报可接受后,手动切换:
```yaml
mode: block
include_modules: [] # 扩至全仓
```
### 6.2 全量启用(观察期结束后)
```yaml
enabled: true
mode: block
include_modules: [] # 空表示全部模块
detection:
patterns: [W01, W02, W03, W04, W05]
```