注:本文Linux环境只跑Beanstalkd,PHP环境还是在Windows
1.介绍:
Beanstalkd 是一个高性能,轻量级的分布式内存队列,最初设计意图是在高并发的网络请求下,通过异步执行耗时较多的请求,及时返回结果,减少请求的响应延迟。
2.特性:
- 优先级(priority):即支持任务插队功能,可以根据需要设置任务被消费的优先次序。
- 延迟(delay):可以设置一个时间t,即任务t秒后才可以被消费者读取。
- 持久化(persistent data):会定时将任务刷新到beanstalkd日志文件中,在服务器宕机等意外发生时,也能保持数据不会丢失。
- 预留(buried):设为预留时,消费者暂时无法取出任务,等某个合适时机再拿出来消费。
- 超时重发(time-to-run):任务必须在指定时间内进行消费,否则就任务消费失败,会重新进入队列,给消费者进行消费。
3.安装:
- Linux下安装Beanstalkd(目前只支持Linux系统),执行命令:apt-get install beanstalkd 即可安装,端口一般为11300,可通过命令:netstat –ntlp查看所有端口的使用情况
- 在laravel中安装扩张包:composer require pda/pheanstalk如果有以下报错,
则需修改composer.json文件即可“ext-json”: “^1.7”改为“ext-json”: “^1.6”
4.使用:
为了能让Windows环境下的PHP连接Linux下的beanstalkd,故需先修改beanstalkd的配置,操作如下:
vim /etc/default/beanstalkd
将BEANSTALKD_LISTEN_ADDR = 127.0.0.1改为BEANSTALKD_LISTEN_ADDR = 0.0.0.0
同时放开BEANSTALKD_EXTRA,放开此参数可以实现持久化,即断电可重新读取队列信息
修改完成后,执行重启命令:service beanstalkd restart
然后可以查看beanstalkd的状态:service beanstalkd status
然后修改beanstalkd.socket的配置,将ListenStream=127.0.0.1:11300修改为ListenStream=0.0.0.0:11300
同样重启一下beanstalkd.socket,但需要先关闭beanstalkd,
然后再开启beanstalkd.socket和beanstalkd
systemctl stop beanstalkd
systemctl start beanstalkd.socket
systemctl start beanstalkd
然后查看beanstalkd.socket的状态
Job的生命周期
Status | Description |
ready | 等待被取出并处理 |
reserved | 如果job被worker取出,将被此worker预订,worker将执行此job |
delayed | 等待一定时间后,状态变为ready |
buried | 等待唤醒,通常job处理失败时 |
生产者将任务放入队列中(注:创建链接的方法可能随版本而有差异,本文中Pheanstalk版本为4.0)
$pheanstalk = Pheanstalk::create('192.168.135.133', 11300);
$pheanstalk->useTube('tube_name')->put('tube',1024,2,60);
通过put()方法将任务插入队列,第一个参数任务body;第二个参数优先级,0-2^32,值越小优先级越高,默认1024;第三个参数延迟的秒数,在这段时间任务处于延迟的状态;第四个参数允许执行的最大秒数,如果任务在这段时间内不能被delete、release、bury,那么任务超时后服务器将release此任务,状态变为ready,最小为1秒。
消费者从队列中获取任务进行
$pheanstalk = Pheanstalk::create('192.168.135.133', 11300);
$job = $pheanstalk->watch('tube_name')->ignore('default')->reserve();
$data= $job->getData();
$pheanstalk->delete($job); //任务处理完成后,将该任务删除
当某个任务多次消费失败时,我们可以将其记录下来(存数据库或文件),并将任务删除掉,防止任务一直重复被消费
$job = $pheanstalkd->watch('tube_name')->ignore('default')->reserve();
$res = $pheanstalkd->statsJob($job);
//尝试5次后,依然失败则记录下来,并删除
if ($res['reserves'] > 5) {
file_put_contents('fail_tube.log', $job->getData()."\n",FILE_APPEND);
$pheanstalkd->delete($job);
} else {
$pheanstalkd->release($job); //将失败的任务release到ready状态
}
5.查看队列任务的命令行工具:beanstool
- 安装:
wget https://github.com/src-d/beanstool/releases/download/v0.2.0/beanstool_v0.2.0_linux_amd64.tar.gz
tar -xvzf beanstool_v0.2.0_linux_amd64.tar.gz
cp beanstool_v0.2.0_linux_amd64/beanstool /usr/local/bin/
- 常用命令
本文参考:https://www.imooc.com/learn/912,https://learnku.com/articles/18687