生产环境唯一可靠方案是Linux系统crontab直接调用php think命令。需在app/command/下定义命令类,crontab条目须cd到项目根目录、用绝对路径PHP、显式指定APP_ENV=production,并重定向日志、确保runtime权限、业务逻辑幂等。

ThinkPHP 定时任务不推荐用 think-crontab 这类第三方扩展,生产环境唯一可靠、可运维的方案是 Linux 系统 crontab 直接调用 php think 命令。框架本身无常驻进程能力,任何依赖 PHP-FPM、Web 请求触发或 sleep 循环的方案都容易漏跑、重复、阻塞或失控。
为什么不用 think-crontab 或自建定时器
think-crontab 是社区封装的模拟调度器,本质仍是基于 HTTP 请求或 CLI 启动后轮询,存在严重缺陷:
- 没有进程守护机制,命令退出即停止,crontab 未配置则任务永久中断
- 无法处理并发冲突,多实例同时运行可能重复执行关键逻辑(如发两次通知)
- 依赖 PHP 进程存活,超时、OOM、信号中断都会导致任务静默失败
- 日志、错误码、权限、环境变量等全靠手动兜底,运维成本高
正确做法:系统 crontab + ThinkPHP 命令行指令
把业务逻辑封装成标准命令行指令,由操作系统内核级调度器准时唤醒——这才是稳定、可观测、可审计的方案。
- 在 app/command/ 下新建类(如
CleanCacheCommand.php),命名空间为app\command,继承think\console\Command -
configure()中用$this->setName('cron:clear')显式注册命令名 -
execute()内直接调用Db::、Cache::、模型等,禁止使用Request或$_SERVER - 返回
0表示成功;非零值会被 crontab 记为失败并触发告警(如有)
crontab 条目必须写对的三个关键点
90% 的“不执行”问题出在环境错位,不是代码写错了:
立即学习“PHP免费学习笔记(深入)”;
-
cd 到项目根目录再执行:crontab 默认工作路径是
/root或/var/spool/cron,不 cd 就找不到think文件和自动加载 -
用绝对路径调用 PHP:写
/usr/bin/php,别写php(crontab 不读用户$PATH) -
显式指定运行环境:加
APP_ENV=production,避免开发配置被误加载
示例条目(每天凌晨2点清缓存):
0 2 * * * cd /var/www/myproject && /usr/bin/php think cron:clear >> /var/log/cron-clear.log 2>&1
配套建议:加日志、设权限、做幂等
- 所有定时任务输出必须重定向到日志文件(
>> /path/to/log 2>&1),方便排查失败原因 -
runtime/目录确保 crontab 执行用户(如root或www-data)有读写权限:chmod -R 775 runtime/ - 业务逻辑自身要幂等:比如清缓存可直接调
Cache::clear();更新状态应加 where 条件(如where('status', 'pending')->where('expire_time', '<', time()))



















