mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 07:22:49 +08:00
docs(timer): 定时器技能新增按时间窗口循环处理的推荐方法
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -34,10 +34,74 @@ description: "内置秒级定时器(php think timer)的使用与扩展规范
|
||||
|
||||
长时间运行任务的推荐写法(仍用 `site`):
|
||||
|
||||
- 设计为“可重入”的短任务:每次 `do()` 只处理一小批数据,处理进度写入缓存/表,下次继续
|
||||
- 设计为"可重入"的短任务:每次 `do()` 只处理一小批数据,处理进度写入缓存/表,下次继续
|
||||
- 结合 `concurrency` 做分片:按 `$this->concurrencyId` 划分数据范围,多个实例并行推进
|
||||
- 结合 `frequency` 控制节奏:用调度频率限制整体吞吐,避免单次占用过久
|
||||
|
||||
#### 按时间窗口循环处理(队列消费推荐)
|
||||
|
||||
适用于:需要持续消费队列/轮询数据的场景(如消息处理、订单状态同步、通知推送等)。
|
||||
|
||||
核心思路:在 `do()` 方法内设置一个**最大执行时间窗口**,循环处理单条数据,超时后自动退出,由定时器下次调度继续。
|
||||
|
||||
```php
|
||||
class MyQueueTask extends TimerController
|
||||
{
|
||||
// 每次执行的最大运行时间(秒),根据业务和定时器 frequency 合理设置
|
||||
// 建议不超过 frequency 的一半,留出调度间隔
|
||||
protected $maxRunTime = 5;
|
||||
|
||||
// 防刷间隔(秒),与定时器侧 frequency 配合
|
||||
protected $frequency = 10;
|
||||
|
||||
public function do()
|
||||
{
|
||||
$maxTime = time() + $this->maxRunTime;
|
||||
|
||||
do {
|
||||
$this->doItem();
|
||||
|
||||
// 超时检查:时间窗口用完则退出,下次调度继续
|
||||
if (time() >= $maxTime) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
protected function doItem()
|
||||
{
|
||||
// 取一条待处理的数据
|
||||
$item = SomeModel::where('status', 0)->order('id', 'asc')->find();
|
||||
|
||||
if (empty($item)) {
|
||||
// 队列为空时短暂休眠,避免空转消耗 CPU
|
||||
sleep(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// ... 处理单条数据的业务逻辑 ...
|
||||
|
||||
$item->status = 1;
|
||||
$item->save();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**要点:**
|
||||
|
||||
| 配置项 | 建议 |
|
||||
|--------|------|
|
||||
| `maxRunTime` | 不超过 `frequency` 的一半;例如 `frequency=10` 时设 3~5 秒 |
|
||||
| `doItem()` 中的 `sleep()` | 队列空时必须休眠,防止 CPU 空转;有数据时不要 sleep |
|
||||
| `doItem()` 的粒度 | 每次只处理一条/一批数据,保证可重入、可中断 |
|
||||
| `frequency` | 与 `maxRunTime` 配合,`frequency` >= `maxRunTime * 2` 为宜 |
|
||||
|
||||
**与普通定时任务的区别:**
|
||||
|
||||
- 普通任务:`do()` 执行一次就返回,靠定时器周期性调度
|
||||
- 时间窗口模式:`do()` 在时间窗口内持续循环消费,处理完积压数据后自动退出
|
||||
- 优势:面对突发积压数据时,单次调度可处理多条,提高吞吐;超时安全退出,不会阻塞定时器
|
||||
|
||||
### 2) 编写任务目标(target)
|
||||
|
||||
#### A. site 类型(HTTP 任务)
|
||||
|
||||
Reference in New Issue
Block a user