安装 pda/pheanstalk 需按 PHP 版本选 v4.0(≥8.1)或 v3.2(7.1–8.0);推荐用 Pheanstalk::create() 初始化,避免连接隐患;putInTube() 比 put() 更安全;reserve 后须 delete/release,否则任务卡死。

composer require pda/pheanstalk 要注意 PHP 版本和版本号写法
直接运行 composer require pda/pheanstalk 很可能失败——不是命令错,而是版本不匹配。Pheanstalk v4.x(当前主流)要求 PHP ≥ 8.1,v3.x 支持 PHP 5.5+;而 Ubuntu 默认 PHP 版本常是 8.1 或 8.2,但如果你用的是旧项目(比如 PHP 7.4),就必须显式指定 v3:composer require pda/pheanstalk:^3.2。
常见错误现象:Could not find package pda/pheanstalk 或安装后 Class 'Pheanstalk\Pheanstalk' not found,大概率是版本与 PHP 不兼容,或 autoloader 没生效(检查 vendor/autoload.php 是否被正确引入)。
- 确认 PHP 版本:
php -v - v4 推荐写法(PHP 8.1+):
composer require pda/pheanstalk:^4.0 - v3 兼容写法(PHP 7.1–8.0):
composer require pda/pheanstalk:^3.2 - 装完立刻验证:
php -r "require 'vendor/autoload.php'; echo class_exists('Pheanstalk\Pheanstalk') ? 'OK' : 'FAIL';"
new Pheanstalk() 和 Pheanstalk::create() 的区别不能忽略
文档里两种写法都出现过,但行为不同:new Pheanstalk('localhost') 是构造函数直连,不校验服务可用性;Pheanstalk::create('localhost', 11300) 是工厂方法,内部会尝试握手并抛出异常(比如连接拒绝时直接报 Connection refused),更适合生产环境做健壮初始化。
容易踩的坑:用 new 实例化后没检查连接状态,结果后续 put() 或 reserve() 报错才暴露问题,排查成本高。
- 推荐始终用
Pheanstalk::create($host, $port) -
端口默认是
11300,别写成1130(少一位) - 如果 Beanstalkd 绑定在非
127.0.0.1(比如0.0.0.0),确保$host和服务监听地址一致
putInTube() 和 put() 的语义差异直接影响任务路由
put() 总是往当前 useTube() 指定的 tube 写入;putInTube('my-tube', $data) 则绕过当前 tube,直接投递到指定 tube。两者底层协议一致,但逻辑隔离性完全不同。
典型误用场景:多个模块共用一个 Pheanstalk 实例,A 模块调用 $pheanstalk->useTube('email')->put(...),B 模块紧接着调用 $pheanstalk->put(...),结果 B 的任务也进了 email tube——因为 useTube() 是实例级状态,不会自动重置。
- 若需强隔离,优先用
putInTube(),避免依赖useTube()的隐式上下文 - Tube 名建议小写、不含空格和特殊字符(如
user_signup✅,User Signup!❌) - 首次向新 tube 写入时,Beanstalkd 会自动创建它;但读取前必须先
watch('tube-name')
reserve() 后必须 delete() 或 release(),否则任务卡死
Beanstalkd 的 reserve 流程是“预留 → 处理 → 确认完成”,一旦 reserve() 成功,该 job 就进入 reserved 状态(current-jobs-reserved +1),且默认 60 秒超时(TTR)。超时未 delete() 或 release(),job 会自动回到 ready 队列,可能被重复消费。
最危险的情况是消费者进程崩溃或未捕获异常,导致 job 永久处于 reserved 状态——既不失败也不成功,监控看不出来,但积压越来越多。
- 务必用
try/catch包裹任务处理逻辑 - 成功:调用
$pheanstalk->delete($job) - 失败需重试:调用
$pheanstalk->release($job, $priority, $delay) - 长任务记得
$pheanstalk->touch($job)延长 TTR,防止被误放回队列
beanstalkd 进程是否存活、防火墙是否放行 11300 端口、以及 watch() 是否漏掉 tube 名拼写,这三处比代码逻辑更容易出问题。










