fiberphp/crontab

⏰ FiberPHP 定时任务 —— 秒级精度调度、多进程执行、Redis 分布式锁、实时日志推送。

Maintainers

Package info

gitee.com/FiberPHP/crontab

Issues

pkg:composer/fiberphp/crontab

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

dev-master 2026-08-24 11:34 UTC

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 数据表即可,CronSchedulerscan_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_type1 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 '清理完成';
    }
}

数据库 commandApp\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