CodeIgniter 3.x 和 4.x 均无内置队列系统,需依赖第三方扩展(如 ci4-queue)或自定义方案;CI4 推荐 Redis/Database 驱动,CI3 仅能通过 Cron + 数据库轮询模拟,部署时须重视进程守护与失败任务清理。

CodeIgniter 本身没有内置队列系统
CodeIgniter(尤其是 3.x 和 4.x)不提供原生的异步任务队列或后台作业调度能力。你看到的“队列”功能,基本都是通过第三方扩展、自定义封装或外部服务桥接实现的。直接调用 $this->queue->push() 或类似方法会报错——因为核心框架压根没定义这个类。
CI4 中推荐用 CodeIgniter-Queue 扩展 + Redis 或 Database 驱动
社区主流方案是使用 kenjis/ci4-queue(或其 fork 维护版),它为 CI4 提供了 Laravel-style 的队列接口,并支持 database、redis、beanstalkd 等后端。安装后需手动配置驱动:
- Redis 配置示例:
config/Queue.php中设置'default' => 'redis',并确保redis扩展已启用 - Database 驱动更轻量:运行迁移命令生成
jobs表,适合小流量项目 - 切勿在控制器中直接
dispatch(new SendEmailJob())后就返回响应——要确保队列监听器(php spark queue:work)正在后台运行 - CI4.3+ 注意:部分旧版扩展与 PSR-14 事件机制冲突,建议优先选支持
CodeIgniter\I18n\Time的新版分支
CI3 只能靠 Cron + 自定义脚本模拟队列行为
CI3 缺乏事件循环和守护进程支持,所谓“队列”本质是定时轮询数据库表 + CLI 命令触发。常见做法:
- 建一张
queued_tasks表,字段含job_class、params(JSON)、attempts、failed_at - 写一个 CLI 命令(如
php index.php tools run_queue),每次拉取status = 'pending'且run_at <= NOW()的任务执行 - 关键陷阱:
cron默认每分钟跑一次,但若某次任务执行超时,下一轮可能并发重叠——必须加FOR UPDATE锁或用status = 'processing'状态隔离 - 别依赖
sleep()实现延迟:PHP CLI 的max_execution_time通常被设为 0,但宿主机资源限制(如 systemd 的TimeoutSec)可能中途杀掉进程
调度定时任务不能只靠 Cron,得结合业务状态校验
很多团队把“每天早上 9 点发报表”直接写成 0 9 * * *,结果发现数据未就绪、上游 API 超时、或前一日批处理失败,导致邮件内容为空。真实场景中必须加前置检查:
- 在调度命令入口处先查
daily_summary_status表,确认status = 'completed'且date = YESTERDAY - CI4 的
spark命令支持参数传入,比如php spark report:send --date=2024-06-15,避免硬编码时间逻辑 - CI3 的 CLI 脚本务必用
set_time_limit(0)开头,否则默认 30 秒超时会让 cron 误判为失败 - 日志输出别只打到
STDERR:cron 默认静默,建议写入write_log('error', ...)或独立文件,方便排查“看似跑了但没效果”的问题
实际部署时最常被忽略的是进程守护——没人盯着 queue:work 是否意外退出,也没人清理 failed_jobs 表。这比选 Redis 还重要。


















