延迟消息队列beanstalkd
beanstalkd是简单、快速的工作队列!
Beanstalkd安装
安装它的v1.12版本。
[root@2207011 resource]# wget https://github.com/beanstalkd/beanstalkd/archive/refs/tags/v1.12.tar.gz
[root@2207011 resource]# tar -zxvf v1.12.tar.gz
[root@2207011 resource]# cd beanstalkd-1.12
[root@2207011 beanstalkd-1.12]# make install PREFIX=/usr/local/beanstalkd-1.1
[root@2207011 beanstalkd-1.12]# ln -s /usr/local/beanstalkd-1.12/ /usr/local/beanstalkd
[root@2207011 beanstalkd-1.12]# cd /usr/local/beanstalkd
[root@2207011 beanstalkd]# ./bin/beanstalkd -h
[root@2207011 beanstalkd]# ./bin/beanstalkd & # 后台运行服务
[root@2207011 beanstalkd]# ps -ef | grep beanstalkd | grep -v grep
root 4367 4144 0 10:25 pts/0 00:00:00 ./bin/beanstalkd
最终看到了beanstalkd进程,安装完成。
Beanstalkd工作原理
我们可以在beanstalkd工作队列服务上创建各种工作job,然后给相应的消费者去预定job处理。
job 的生命周期
Client 使用 put 命令创建一个工作任务 job. 在整个生命周期中 job 可能有四个工作状态:ready、reserved、delayed、buried. 在 put 操作之后,一个 job 的典型状态是 ready,在 ready 队列中,它将等待一个 worker 取出此 job 并设置为其为 reserved 状态. worker占有此 job 并执行,当 job 执行完毕,worker 可以发送一个 delete 指令删除此 job.
| Status | Description |
|---|---|
ready |
等待被取出并处理 |
reserved |
如果 job 被 worker 取出,将被此 worker 预订,worker 将执行此 job |
delayed |
等待特定时间之后,状态再迁移为 ready 状态 |
buried |
等待唤醒,通常在 job 处理失败时进入该状态 |
job 典型的生命周期
put reserve delete
-----> [READY] ---------> [RESERVED] --------> *poof*
job 可能的状态迁移
put with delay release with delay
----------------> [DELAYED] <------------.
| |
kick | (time passes) |
| |
put v reserve | delete
-----------------> [READY] ---------> [RESERVED] --------> *poof*
^ ^ | |
| \ release | |
| `-------------' |
| |
| kick |
| |
| bury |
[BURIED] <---------------'
|
| delete
`--------> *poof*
Tubes
一个 beanstalkd 实例服务可能有一个或者多个 tube,用来储存统一类型的 job.每个 tube 由一个就绪 (ready) 队列与延迟 (delayed) 队列组成.每个 job 所有的状态迁移在一个 tube 中完成.通过发送 watch 指令, 消费者 consumers 可以监控感兴趣的 tube.通过发送 ignore 指令, 消费者 consumers 可以取消监控 tube.通过 list-tubes-watched命令返回所有监控的 tubes,当客户端预订 (reserved) 一个 job,此 job 可能来自任何一个它监控的 tube.
当一个客户端连接上服务器时,客户端监控的 tube 默认为 defaut,如果客户端提交 job 时,没有使用 use 命令,那么这些 job 就存于名为default的 tube 中.
tube 按需求创建,无论他们在什么时候被引用到.如果一个 tube 变为空(即 no ready jobs,no delayed jobs,no buried jobs)和没有任何客户端引用(being watched),它将会被自动删除.
应用示例:
使用pheanstalk4.0.4的php客户端测试发布延迟工作
$beanstalkd = Pheanstalk::create('beanstalkd服务地址');
// 在success管道上创建一个延迟6s的工作
$beanstalkd->useTube('success')->put("content: cooking dinner, create time: " . date('Y-m-d H:i:s'), 1024, 6, 3);
// 消费该工作
$beanstalkd->watch('success');
while (true) {
echo sprintf("time: %s\n", date('Y-m-d H:i:s'));
try {
// 每秒预定一次工作(实际这里是堵塞1s 根据实际情况设置)
$job = $beanstalkd->reserveWithTimeout(1);
if ($job) {
echo sprintf("time: %s, do job\n%s\n", date('Y-m-d H:i:s'), $job->getData());
// ...处理工作
// 处理完工作删除它
$beanstalkd->useTube('success')->delete($job);
}
} catch (\Throwable $e) {
echo sprintf("demo exception: %s\n" . $e->getMessage());
}
}

浙公网安备 33010602011771号