Files
kiri-crontab/README.md
T

120 lines
3.0 KiB
Markdown
Raw Normal View History

2026-06-28 17:06:12 +08:00
# kiri-crontab
基于 Redis + Swoole 的 PHP 定时任务调度系统。
## 功能特性
- **闹钟模式**: 像设置闹钟一样声明任务 `hour: 3, minute: 0, loop: true`
- **间隔执行**: `tick: 30` 每30秒、`tickMinute: 5` 每5分钟、`tickHour: 1` 每1小时
- **一次性任务**: `year: 2026, month: 12, day: 22, hour: 11` 指定时刻执行一次
- **Cron 兜底**: 复杂场景用 `cron: '*/5 * * * *'`
- **动态投递**: 运行时通过 `submitToCrontab()` 随时提交、`cancelCrontabTask()` 取消
- **类注解**: `#[Crontab]` 在类上声明调度参数,CrontabProcess 启动时自动发现
- **协程并发**: 到期任务通过 Swoole 协程并发执行
- **分布式锁**: Redis 主锁 + 任务锁防止重复执行
## 快速开始
### 安装
```bash
composer require game-worker/kiri-crontab
```
### 注解模式
```php
<?php
namespace App\Task;
use Kiri\Crontab\Annotate\Crontab;
use Kiri\Crontab\TaskInterface;
#[Crontab(name: '清理日志', hour: 3, minute: 0, loop: true)]
class CleanLogTask implements TaskInterface
{
public function handle(): void
{
echo "清理日志..." . PHP_EOL;
}
}
#[Crontab(name: '心跳', tick: 30, loop: true)]
class HeartbeatTask implements TaskInterface
{
public function handle(): void
{
echo "心跳检测..." . PHP_EOL;
}
}
```
### 动态投递
```php
use function Kiri\Crontab\submitToCrontab;
use function Kiri\Crontab\cancelCrontabTask;
// 每秒检查匹配结果,匹配成功后在 handle() 中自停
class MatchCheckTask implements TaskInterface
{
public function handle(): void
{
if ($this->isMatched()) {
// 执行完后自动移除,不再调度
CrontabScheduler::getInstance()?->cancelCurrentTask();
return;
}
// 未匹配,继续检查
}
}
// 业务代码中动态投递
$taskKey = submitToCrontab(MatchCheckTask::class, 'every:1', '匹配检查 #123');
// 条件满足时也可以外部取消
cancelCrontabTask($taskKey);
```
### 配置文件
```php
// config/crontab.php
return [
'redis' => ['host' => '127.0.0.1', 'port' => 6379],
'scheduler' => ['tick_interval' => 1],
'tasks' => [
['class' => App\Task\CleanLogTask::class, 'name' => '清理日志', 'expression' => 'daily:03:00'],
],
];
```
### 启动
```bash
php bin/crontab start / stop / restart / status
```
### 集成到 kiri-core
```php
// config/servers.php
'process' => [\Kiri\Crontab\CrontabProcess::class],
```
## 调度参数一览
| 参数 | 示例 | 含义 |
|------|------|------|
| `tick` | `tick: 30` | 每 30 秒循环 |
| `tickMinute` | `tickMinute: 5` | 每 5 分钟循环 |
| `tickHour` | `tickHour: 1` | 每 1 小时循环 |
| `hour` `minute` `second` | `hour: 3, minute: 0, loop: true` | 每天 03:00 |
| `minute` | `minute: 30, loop: true` | 每小时 :30 |
| `year` `month` `day` ... | `year: 2026, month: 12, day: 22` | 指定时刻一次性 |
| `cron` | `cron: '*\/5 * * * *'` | cron 表达式 |
## 架构
详见 [DESIGN.md](./DESIGN.md)