Beanstalk服务安装及PHP队列开发
一:Beanstalk介绍
Beanstalk是一个基于内存的(binlog持久化到硬盘),事件驱动(libevent),简单、快速的任务队列,支持大部分编程语言,将前台的任务转为后台异步处理,为web开发提供更高弹性。它可以支持多个server(客户端支持),一个任务只会被投递到一台server,一个任务只会被一个消费者获取(Reverse)。
使用Beanstalk任务队列提升PHP异步处理能力,降低程序耦合度,使前台更专注,后台处理耗时、扩展性任务(也可以使用其他语言开发),使得web架构更具扩展性。
相比RabbitMQ,Beanstalk作为一个任务队列,设计比较简单,支持以下特性:
- 优先级(priority),可以对任务进行优先处理(或降级),越小的值优先级越高(0~4,294,967,295),默认按先进先出(FIFO)
- 延迟执行(delay),一个任务创建完成并稍后再执行(比如等待主从同步)
- 超时重试(TTR),一个任务没有在指定时间内完成,将会被重新投递,由其他客户端处理。客户端也可以主动进行延时(touch)或重新入队(release)
- 隐藏(bury),一个任务执行失败了,可以先隐藏,隐藏的任务可以被重新激活(kick).
二:CentOS下安装Beanstalkd
1 2 3 4 5 6 7 8 9 |
[root@bogon tmp]# wget https://github.com/kr/beanstalkd/archive/v1.10.tar.gz [root@bogon tmp]# cd beanstalkd-1.10/ [root@bogon beanstalkd-1.10]# make install [root@bogon beanstalkd-1.10]# beanstalkd -v beanstalkd 1.10 #启动服务,没有后台启动服务,在命令之后加了个&人工后台 [root@bogon /]# beanstalkd -l 192.168.33.11 -p 11300 & [root@bogon tmp]# ps -ef | grep "beanstalkd" root 4795 3285 0 15:38 pts/0 00:00:00 /usr/local/bin/beanstalkd -l 192.168.33.11 -p 11300 |
后台启动:
beanstalkd -l 地址 -p 端口号 -z 最大的任务大小(byte) -c &
如果是外部客户端连接,ip地址要写外网地址,这样才能连接上
启动选项:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
-b DIR wal directory -f MS fsync at most once every MS milliseconds (use -f0 for "always fsync") -F never fsync (default) -l ADDR listen on address (default is 0.0.0.0) -p PORT listen on port (default is 11300) -u USER become user and group -z BYTES set the maximum job size in bytes (default is 65535) -s BYTES set the size of each wal file (default is 10485760) (will be rounded up to a multiple of 512 bytes) -c compact the binlog (default) -n do not compact the binlog -v show version information -V increase verbosity -h show this help |
注:由于Beanstalk服务端实现的比较简单,协议特性需要客户端支持,不同的实现可能效果不一样。下面使用的是这个库:PHP Beanstalkd。php扩展的客户端并没有实现延时发送(delay),超时重试(TTR),因此不建议使用。
shell启动脚本:
1 2 3 4 5 6 7 8 9 10 11 |
vim checkbeanstalkd.sh count=`ps -fe |grep "beanstalkd" | grep -v "grep" | wc -l` if [ $count -lt 1 ]; then nohup /usr/local/bin/beanstalkd -b /tmp/ & echo $(date +%Y-%m-%d_%H:%M:%S) >/tmp/btrestart.log fi crontab -e */1 * * * * /usr/local/nginx/beanstalkd/checkbeanstalkd.sh |
三:php使用beanstalk
1 2 3 4 5 6 7 8 9 10 |
<?php include 'lib/Beanstalk.php'; $bean = Beanstalk::init(); $bean->addServer('192.168.33.11', 11300); $bean->useTube('my-tube'); $bean->put('Hello World!', 1024); $bean->put(json_encode(array('what','how')), 1000, 1, 1); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
include 'lib/Beanstalk.php'; $bean = Beanstalk::init(); $arrServer = [ ['server' => '192.168.33.11', 'port' => '11300'], ['server' => '192.168.33.19', 'port' => '11300'] ]; foreach($arrServer as $r){ $bean->addServer($r['server'], $r['port']); } $bean->watchTube('my-tube'); while (true) { try { $job = $bean->reserve($timeout = 10); var_dump($job); $res = xxxxxxxx; //process job if(!$res){ $job->delete(); } else{ $job->bury(); } } catch (BeanstalkException $e) { switch ($e->getCode()) { case BeanstalkException::TIMED_OUT: echo "Timed out waiting for a job. Retrying in 1 second."; sleep(1); continue; break; default: throw $e; break; } } } |
发表评论