codeigniter原生不支持beanstalkd,需手动集成pheanstalk客户端;常见连接失败因sockets扩展未启用、地址配置错误或服务未运行;worker须脱离ci框架独立部署并做好异常重连与任务幂等处理。

CodeIgniter 本身不内置 Beanstalkd 支持,所谓“Beanstalkd_CodeIgniter 任务队列系统”并不是官方组件或广泛认可的成熟包,直接安装即用基本不可行。你看到的可能是某个小众封装、过时的第三方库(如 ci-beanstalk),或开发者自行集成的方案——这意味着必须手动对接,且需格外注意连接生命周期、异常隔离和 worker 启停逻辑。
为什么 beanstalkd_connect() 总是返回 false?
CodeIgniter 没有原生 Beanstalkd 客户端,多数人会用 pda/pheanstalk(PHP Beanstalkd 客户端)。常见失败原因不是代码写错,而是环境配置被忽略:
-
pheanstalk需要 PHP 的sockets扩展启用(extension=sockets在php.ini中),仅装 Composer 包不够 - 默认连接地址是
127.0.0.1:11300,但 CI 运行在 Docker 或远程服务器时,localhost可能解析失败,应显式指定 IP - CI 的 Autoloader 不自动加载
Pheanstalk\Pheanstalk,需在application/config/autoload.php中补上'libraries' => ['pheanstalk'],或在控制器/模型里手动require_once - Beanstalkd 服务未运行,或防火墙拦截了 11300 端口(可用
telnet 127.0.0.1 11300测试连通性)
如何在 CI 控制器里安全地 put 一条 job?
不能直接 new Pheanstalk 在每次 HTTP 请求中创建连接,否则连接数暴涨、超时频发。推荐封装成 CI Library,并复用连接:
// application/libraries/Beanstalk_lib.php
class Beanstalk_lib {
private $pheanstalk;
public function __construct() {
$this->pheanstalk = new \Pheanstalk\Pheanstalk('127.0.0.1', 11300, 1);
}
public function push($tube, $data) {
try {
return $this->pheanstalk->useTube($tube)->put(json_encode($data));
} catch (\Pheanstalk\Exception\ConnectionException $e) {
log_message('error', 'Beanstalk connection failed: ' . $e->getMessage());
return false;
}
}
}
调用时:$this->load->library('beanstalk'); → $this->beanstalk->push('send_email', ['to' => 'a@b.c', 'template' => 'welcome']);
注意:job 数据必须可 JSON 序列化;不要传 CI 对象(如 $this、$this->db),worker 端无法还原。
worker 脚本为什么一跑就退出,且不处理 job?
Beanstalkd worker 是长进程,而 CI 默认设计为短生命周期(一次请求即销毁)。直接用 CI 命令行跑控制器会因 Auto-loader、Router 初始化失败而报错。正确做法是脱离 CI 框架启动独立 worker:
- 写一个纯 PHP CLI 脚本(如
worker.php),只 requirepheanstalk和你的业务类,不 load CI 核心 - worker 内必须手动重连:
reserve()超时后连接可能断开,需捕获\Pheanstalk\Exception\ConnectionException并重建实例 - job 处理失败时,别直接
delete(),先bury()或release()(带 delay),避免丢任务 - 用
nohup php worker.php > /dev/null 2>&1 &启动,配合supervisord管理进程,否则终端关闭 worker 就死
Beanstalkd 的核心约束很硬:没有延迟队列原语(只能靠 put($data, $pri, $delay, $ttr) 的 $delay)、无优先级抢占、无任务去重。这些得靠你在 $data 结构里加时间戳、唯一 ID,再在 worker 里做幂等判断——框架不会替你兜底。











