beanstalkd是轻量级高性能分布式任务队列,支持延迟投递、优先级和预留机制;通过put的$delay参数实现定时任务,配合pheanstalk客户端及binlog持久化保障可靠性。

Beanstalkd 是一个轻量级、高性能的分布式任务队列系统,天然支持延迟投递(delay)、优先级(priority)和预留(reserve)机制,非常适合在 PHP 中实现延迟队列。关键在于合理利用 put 命令的 $delay 参数,配合消费者端的正确处理逻辑。
安装与启动 Beanstalkd 服务
确保 Beanstalkd 已安装并运行:
- Linux(如 Ubuntu/Debian):
sudo apt install beanstalkd,然后确认服务已启用:sudo systemctl enable beanstalkd && sudo systemctl start beanstalkd - macOS:
brew install beanstalkd,启动:beanstalkd -l 127.0.0.1 -p 11300 & - 默认监听
127.0.0.1:11300,可通过telnet 127.0.0.1 11300测试连通性
PHP 端接入:使用 Pheanstalk 客户端
推荐使用官方维护的 Pheanstalk 库(v4+ 支持 PHP 8):
- 安装:
composer require pda/pheanstalk - 延迟任务投递示例(比如 60 秒后执行发短信):
use Pheanstalk\Pheanstalk;
$pheanstalk = new Pheanstalk('127.0.0.1', 11300);
$data = json_encode(['mobile' => '13800138000', 'content' => '订单已超时']);
// delay=60 表示 60 秒后该 job 才变为 ready 状态
$pheanstalk->useTube('sms_delay')->put($data, Pheanstalk::DEFAULT_PRIORITY, 60, 300); // ttr=300秒
注意:第 3 个参数是 $delay(秒),第 4 个是 $ttr(Time-To-Run,任务最长执行时间,超时会自动释放回 ready 队列)。
消费者端:可靠消费与重试逻辑
延迟任务不会“自动触发”,而是等 delay 过期后变成 ready 状态,由消费者 reserve() 拿到并处理:
- 消费者需长运行(如 CLI 脚本),持续调用
reserve();若无任务会阻塞(可设超时避免永久等待) - 成功处理后必须调用
delete($job),否则任务会重入队列(因未确认完成) - 失败时建议
bury($job)归档或release($job, $priority, $delay)延迟重试(例如再延 5 分钟) - 避免死循环:对反复失败的任务,可记录日志 + 埋点告警,或转入死信 tube(如
sms_delay_dlq)
生产环境注意事项
Beanstalkd 本身不持久化(内存存储),重启即丢数据。如需保障可靠性:
- 启用
-b /path/to/binlog启动参数开启 binlog 持久化(推荐) - 监控 tube 的
current-jobs-ready和current-jobs-buried指标,及时发现堆积或异常 bury - 不要在延迟时间中传入负数或非整数——
$delay必须为 ≥ 0 的整数秒 - 高并发场景下,单个 tube 可承载万级 QPS,但建议按业务域拆分 tube(如
order_timeout、coupon_expire),便于隔离与监控
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











