fiberphp / crontab
⏰ FiberPHP 定时任务 —— 秒级精度调度、多进程执行、Redis 分布式锁、实时日志推送。
dev-master
2026-08-24 11:34 UTC
Requires
- php: >=8.3
- ext-redis: *
- fiberphp/console: dev-master
- fiberphp/database: dev-master
- fiberphp/framework: dev-master
- fiberphp/log: dev-master
- fiberphp/redis: dev-master
- symfony/process: ^7.0
- workerman/http-client: ^3.0
- workerman/workerman: ^5.1
Requires (Dev)
- phpunit/phpunit: ^11.0
Suggests
- fiberphp/tracing: Enables distributed tracing for crontab task execution (trace context propagation across scheduler→executor processes).
This package is auto-updated.
Last update: 2026-08-24 11:36:36 UTC
README
Crontab 是 FiberPHP 框架的定时任务子包,基于 Workerman 多进程架构,支持秒级精度调度、协程执行、实时日志监控和 Redis 分布式锁。
核心特性
- 秒级精度调度:内置 6/7 位 Crontab 表达式解析器(含秒字段),精确到秒
- 多进程隔离:调度器、执行器、WebSocket 日志服务三个独立进程,互不干扰
- 协程支持:
enable_coroutine=true时使用 Workerman Coroutine 执行 I/O 密集型任务 - 实时日志推送:WebSocket 服务订阅 Redis channel,浏览器端实时可见执行日志
- 分布式锁:Redis SET NX EX 分布式锁,多实例部署任务不重复执行
- 多任务类型:Console Command / Class 静态方法 / URL HTTP 请求 / Shell 子进程
- 平滑重启:onStop 标志位 + Workerman 信号机制,确保任务不丢失
环境要求
- PHP >= 8.3
ext-redis(Redis 驱动必备)- FiberPHP Framework
- Workerman >= 5.1
- 任一 database driver(
fiberphp/database-mysql/sqlite/pgsql)用于存放任务表
安装
composer require fiberphp/crontab
PackageInstaller::discover 会自动把以下文件拷贝到应用(存在时不覆盖):
config/crontab.php ← 顶层配置(enable / scan_interval / 表名 / 队列 / 锁 / 日志)
config/process/crontab.php ← 三个 crontab Worker 进程声明
导入数据库表:
mysql -u root -p your_database < vendor/fiberphp/crontab/crontab.sql
配置
config/crontab.php:
return [
'enable' => true,
'enable_coroutine' => true, // Workerman Coroutine 执行器 or Timer 异步
'scan_interval' => 5, // 调度器扫描间隔(秒)
'table_cron' => 'crontab', // 任务表
'table_log' => 'crontab_log', // 执行日志表
'cron_queue' => 'crontab:cron_queue', // Redis 就绪队列(LPUSH / BRPOP)
'lock_prefix' => 'crontab:lock:', // 分布式锁 KEY 前缀
'log_subscribe' => 'crontab:logs', // 实时日志 Redis Pub/Sub 频道
'log_write_file' => false, // 同时写 PSR-3 logger
];
config/process/crontab.php(Install 注入后可自行修改端口/进程数):
return [
'scheduler' => [
'handler' => \FiberPHP\Crontab\Process\CronScheduler::class,
'listen' => 'text://0.0.0.0:12346', // TCP 控制端口,供 Client 调用
'count' => 1,
],
'exec' => [
'handler' => \FiberPHP\Crontab\Process\CronExec::class,
'listen' => 'text://0.0.0.0:12347',
'count' => 1,
],
'websocket' => [
'handler' => \FiberPHP\Crontab\Process\LogSocket::class,
'listen' => 'websocket://0.0.0.0:12348',
'count' => 1,
],
];
添加任务(无需重启服务)
直接写入 crontab 数据表即可,CronScheduler 每 scan_interval 秒扫描一次:
INSERT INTO `crontab`
(`name`, `cron_expression`, `task_type`, `command`, `status`)
VALUES
('清理缓存', '0 0 2 * * *', 2, 'App\\Task\\ClearCache::run', 0),
('调用报表 URL', '*/30 * * * *', 3, 'https://app.test/report/generate', 0),
('每日对账', '0 5 0 * * *', 1, 'fiber reconcile:daily', 0),
('清理临时目录', '0 10 3 * * 0', 4, 'rm -rf /tmp/app-*', 0);
task_type:1 Console Command · 2 Class::method · 3 URL(HTTP GET) · 4 Shell。
代码操作(通过 TCP 客户端与调度器进程通信):
use FiberPHP\Crontab\Client;
$client = new Client();
// 创建 / 列表 / 日志 / 立即执行 / 启动 / 暂停 / 重启 / 编辑
$client->request(['method' => 'createTask', 'args' => ['name' => 'test', /* ... */]]);
$client->request(['method' => 'getList', 'args' => ['paginate' => ['page' => 1, 'list_rows' => 20]]]);
$client->request(['method' => 'getTaskLogs', 'args' => ['where' => ['crontab_id' => 1]]]);
$client->request(['method' => 'executeImmediately', 'args' => ['id' => 1]]);
$client->request(['method' => 'reloadTask', 'args' => ['id' => 1]]);
$client->request(['method' => 'closeTask', 'args' => ['id' => 1]]);
$client->request(['method' => 'restartTask', 'args' => ['id' => 1]]);
$client->request(['method' => 'updateTask', 'args' => ['id' => 1, 'cron_expression' => '0 */5 * * * *']]);
助手函数(从容器拿 Client 单例):
crontab()->request(['method' => 'getList', 'args' => []]);
自定义任务(Class 类型)
namespace App\Task;
class ClearCache
{
public static function run(array $params = []): string
{
// 业务逻辑
return '清理完成';
}
}
数据库 command 填 App\Task\ClearCache::run,如需传参写 App\Task\ClearCache::run({"max": 100})(JSON)或传统位置参数形式。
实时日志监控
ws://0.0.0.0:12348 连接后:
{"type":"subscribe","channel":"crontab:logs"}
随后每条执行日志会以 JSON 推送:
{
"type": "log",
"channel": "crontab:logs",
"data": {
"task_id": 1,
"log_id": 1023,
"level": "success",
"message": "类方法执行成功: ...",
"pid": 31424,
"timestamp": 1766410111
},
"timestamp": 1766410111
}
架构
MySQL crontab 表
│
▼ scan_interval 秒级扫描
CronScheduler 进程(text:12346 控制端口 + onMessage CRUD)
│ LPUSH
▼
Redis List(crontab:cron_queue)
│ BRPOP timeout=1
▼
CronExec 进程(CoroutineExec / AsyncTaskExec 四种任务类型)
│ ├─ command/shell → symfony/process 子进程
│ ├─ class → ClassExec::execute 静态调用(支持 JSON/位置/常量表参数)
│ └─ url → Workerman\Http\Client
│
└─── PUBLISH ──► Redis Pub/Sub (crontab:logs)
│
▼
LogSocket WebSocket(ws:12348)
│
▼ 浏览器 / API 客户端订阅
License
MIT