docs(timer): 更新 SKILL.md 和 PROJECT.md 多节点协调文档

T13: E2E single-node regression - all PASS
T14: E2E multi-node coordination - 7/7 PASS
T15: Document multi-node features in ulthon-timer SKILL.md and PROJECT.md
This commit is contained in:
augushong
2026-05-26 03:05:54 +08:00
parent 90e584f5a1
commit 6dceb028b3
2 changed files with 76 additions and 2 deletions

View File

@@ -27,4 +27,25 @@
开发过程中补充的业务规则、团队偏好与临时约束,按条新增。规则应可执行、可复现、可验证。 开发过程中补充的业务规则、团队偏好与临时约束,按条新增。规则应可执行、可复现、可验证。
(待填写。) ### 2026-05-26: 定时任务多节点协调
新增功能:
- 多节点定时任务协调(数据库为主协调中心)
- run_type 调度auto/main/all/manual
- 主节点自动选举 + 手动切换
- 执行日志记录与查看
- 定时任务配置管理 UI
- 日志清理命令 `php think admin:timer:log:clean`
新增数据表:
- ul_system_timer_config
- ul_system_timer_log
- ul_system_host 新增 is_master 字段
新增命令:
- admin:timer:log:clean [--days=30]
新增管理页面:
- 定时器配置管理 (/admin/system.timer_config/index)
- 定时器执行日志 (/admin/system.timer_log/index)
- 主机列表增强(主节点标识、切换主节点)

View File

@@ -83,7 +83,7 @@ description: "内置秒级定时器php think timer的使用与扩展规范
- `call`callable - `call`callable
- `frequency`:执行频率(秒),小于 0 会被修正为 0 - `frequency`:执行频率(秒),小于 0 会被修正为 0
- `concurrency`:并发数量(默认 1`site` 类型会自动把并发参数写入 query - `concurrency`:并发数量(默认 1`site` 类型会自动把并发参数写入 query
- `run_type`保留字段(当前未参与调度逻辑) - `run_type`调度策略(仅对 `site` 类型生效,`call` 类型不受影响)。可选值见「多节点协调 > run_type 调度」
示例site 示例site
@@ -138,3 +138,56 @@ site 任务会按站点域名发起请求,默认从 `sysconfig('site','site_do
- `name` 重复:会导致 Cache key 冲突,表现为任务“莫名其妙不跑/跑得不对” - `name` 重复:会导致 Cache key 冲突,表现为任务“莫名其妙不跑/跑得不对”
- `concurrency` 与控制器侧 `$concurrency` 不一致:会触发 `concurrency id/count error` - `concurrency` 与控制器侧 `$concurrency` 不一致:会触发 `concurrency id/count error`
- 只依赖控制器侧 `$frequency`:它只是防刷,不是调度;调度频率以定时器侧 Cache 节流为准 - 只依赖控制器侧 `$frequency`:它只是防刷,不是调度;调度频率以定时器侧 Cache 节流为准
## 多节点协调
定时器支持多节点部署以数据库MySQL作为协调中心。多个节点连接同一个数据库即可自动组成集群。
### 节点注册
每个节点启动后通过 `system_host_register` call 任务自动注册心跳(每 30 秒一次)。节点 ID 生成规则为 `{hostname}-{8位md5}`,持久化在 `runtime/node_id.lock` 文件中,重启后保持不变。
### 主节点选举
- 第一个注册的节点自动成为主节点
- 管理员可在主机列表页面手动切换主节点
- 相关 API`HostService::setMasterNode()` / `HostService::getMasterNode()`
### run_type 调度
`run_type` 仅对 `site` 类型任务生效,`call` 类型任务始终在所有节点执行。可选值:
| run_type | 行为 | 适用场景 |
|----------|------|----------|
| `auto`(默认) | 两阶段 DB 行锁竞争BEGIN / SELECT FOR UPDATE / UPDATE / COMMIT 抢占,抢占成功后释放锁再执行。每个频率窗口内只有一个节点执行 | 通用场景 |
| `main` | 仅主节点执行 | 需要集中处理的任务 |
| `all` | 所有节点各自独立执行 | 节点本地清理等 |
| `manual` | 仅当 DB 中 `manual_trigger=1` 时执行,执行后自动重置为 0。通过管理后台触发 | 运维手动触发 |
### 配置同步
`TimerService::syncConfigToDatabase()` 在定时器启动时运行,将 PHP 配置文件中的任务同步到 `system_timer_config` 表。同步时不会覆盖数据库中已管理的字段(`run_type``status`),以管理后台的设置为准。
### 执行日志
`TimerControllerBase` 提供 `logStart()` / `logEnd()` 方法记录执行日志。`host_id` 会自动注入到 site 任务的 URL 参数中,用于标识执行节点。
### 管理后台
| 页面 | 路径 | 功能 |
|------|------|------|
| 定时器配置 | `/admin/system.timer_config/index` | 管理 run_type、status、手动触发 |
| 定时器日志 | `/admin/system.timer_log/index` | 只读执行日志查看 |
| 主机列表 | `/admin/system.host/index` | 节点状态、主节点管理 |
### 日志清理
```bash
php think admin:timer:log:clean --days=30
```
### 相关数据表
- `ul_system_timer_config`任务协调配置run_type、status、manual_trigger 等)
- `ul_system_timer_log`:执行日志记录
- `ul_system_host`:新增 `is_master` 字段,标识主节点