ThinkPHP 5.1 定时任务性能优化核心是用Linux Crontab替代Web触发、命令行指令幂等轻量、Redis队列解耦执行、数据库连接分离及失败重试策略,确保调度精准、执行稳定、资源可控。

ThinkPHP 5.1 定时任务性能优化,核心是避开框架生命周期限制、减少资源争抢、防止重复执行,并让调度与执行解耦。单纯靠 think:timer 或 Web 请求触发不可靠,真正有效的优化不是“怎么写得更漂亮”,而是“怎么跑得更稳、更快、不卡”。
用 Linux Crontab 替代 Web 触发
Crontab 是操作系统级调度器,精度高、不依赖请求、不受 PHP-FPM 超时影响。ThinkPHP 自身没有常驻进程能力,任何基于 `app_end` 行为钩子或 HTTP 接口的方案,在低流量或页面未被访问时都会漏跑。 - 必须用绝对路径调用 PHP 解释器,例如 `/usr/bin/php`(通过 `which php` 确认) - 每条 crontab 命令前加 `cd /var/www/your-project && `,确保自动加载和配置文件能正确读取 - 显式声明环境变量:`APP_ENV=production`,避免开发配置误生效 - 日志单独重定向,例如 `>> /var/log/task-device.log 2>&1`,便于排查失败原因命令行指令必须幂等且轻量
定时任务入口(如 `php think device:check`)本身不应做耗时操作,只负责“发号施令”。 - `execute()` 方法里只做三件事:参数校验、入队、返回提示 - 所有数据库查询、HTTP 请求、文件写入全部移交到队列 Job 中执行 - 在入队前加简单锁判断,例如 `Cache::has('device_check_' . date('YmdHi'))`,过期设为 120 秒,防止同一分钟内重复推送 - 避免把大数组、resource、闭包传进队列,序列化失败会导致消息堆积用 Redis 队列承接真实业务逻辑
ThinkPHP 官方推荐的 `think-queue` + Redis 是最成熟解耦方案,比直接在 Cron 进程里执行更安全。 - `queue.php` 配置中 `connector` 设为 `redis`,`host`、`port`、`database` 明确指向生产 Redis 实例 - 启动独立消费进程:`php think queue:listen --queue default --tries 3 --delay 10` - Job 的 `fire()` 方法开头检查是否已处理过(比如查表标记 `task_log` 中是否存在同 batch_id 记录) - 单条消息数据体积控制在 512KB 内,超限就存 DB,只传 ID 进队列分离数据库连接与连接池
定时任务高频执行时,容易因 MySQL 连接数打满导致主站报错。 - 在队列 Job 中显式关闭连接:`Db::close()` 或 `Db::getInstance()->close()`(TP5.1 支持) - 若使用 PDO,可在 `database.php` 中设置 `'deploy' => 0, 'rw_separate' => false`,禁用读写分离干扰 - 对于清理类任务(如日志归档),改用原生 SQL + `PDO::exec()` 绕过 ORM 开销,速度提升明显不复杂但容易忽略。



















