codeigniter不内置beanstalkd支持,须手动集成pda/pheanstalk客户端;安装后需封装为服务类或库,避免每次请求新建连接,并配置超时、重试及异常处理。

CodeIgniter 本身不内置 Beanstalkd 支持,要使用 Beanstalkd 做任务队列,必须手动集成第三方客户端库,并自行封装成可复用的服务类——没有现成的 library 或 spark 能开箱即用。
如何安装并连接 Beanstalkd 客户端
CodeIgniter 3/4 都不自带 Beanstalkd 驱动,推荐用 pda/pheanstalk(PHP 原生 Beanstalkd 客户端),它轻量、无依赖、维护活跃。通过 Composer 安装:
composer require pda/pheanstalk
安装后,在 CodeIgniter 中初始化连接时要注意:不要在每个控制器里重复 new Pheanstalk\Pheanstalk,应封装为服务类或单例。常见错误是忽略连接超时和重试逻辑,导致队列写入失败却不报错:
- 务必设置
connectTimeout和timeout参数,例如new Pheanstalk\Pheanstalk('127.0.0.1', 11300, 1) - 生产环境建议包装
try/catch捕获Pheanstalk\Exception\ConnectionException - CI4 可注册为
service,CI3 推荐放在application/libraries/下并用$this->load->library('beanstalk')
如何向 Beanstalkd 推送任务(put)
推送任务本质是调用 put() 方法,但内容必须是字符串(JSON 序列化最稳妥)。不能直接传对象或数组,否则会触发序列化警告或静默失败:
- 任务数据建议用
json_encode(['job' => 'send_email', 'to' => 'user@example.com']) - 避免使用
serialize(),PHP 反序列化在不同环境可能不兼容 -
put()第二个参数是优先级(int,默认 1024),数值越小优先级越高;第三个是延迟(秒),第四个是 TTL(任务保留时间) - CI3 中若用
$this->beanstalk->put($data),需确保$data是 string 类型,否则会报TypeError
如何监听并执行 Beanstalkd 任务(reserve / delete)
监听不是“常驻进程”,而是由外部调度器(如 supervisord 或 cron)定期拉起 CLI 脚本。常见误区是试图在 Web 请求中 reserve() 并阻塞等待,这会导致 HTTP 超时:
- 必须用 CLI 运行:例如
php index.php tools queue_worker -
reserve(5)的 5 是超时秒数,返回null表示超时,不是错误,需循环处理 - 成功处理后必须显式调用
delete($job),否则任务会在 TTL 后自动释放回 ready 状态,造成重复执行 - 遇到异常时应调用
bury($job)或release($job, $priority, $delay),避免任务丢失
为什么 CI 的 autoload 和 hooks 很难适配 Beanstalkd 工作流
Beanstalkd worker 是长生命周期 CLI 进程,而 CodeIgniter 的 autoload.php 和 hooks 是为单次 HTTP 请求设计的。直接复用会导致配置加载混乱、数据库连接泄漏、Session 冲突等问题:
- 不要在 worker 中调用
$this->load->database()后不关闭,CI3 的mysqli连接不会自动回收 - 避免启用
session_start()或依赖$_SESSION,CLI 环境无 session 上下文 - CI4 的
.env可被读取,但 CI3 的config/autoload.php若含路径硬编码(如APPPATH.'third_party/...'),在 CLI 下可能解析错误 - 最佳实践:worker 脚本绕过 CI 入口,只 require 必需类,用原生 PDO 或轻量 DB 封装操作数据库
真正麻烦的从来不是“怎么发一个 job”,而是 worker 进程的启停管理、失败重试边界、任务幂等性保障——这些没法靠封装一个 Beanstalk_lib 解决,得结合 supervisord 日志、Beanstalkd 自带的 stats 和业务层唯一键校验一起做。











