本地通过docker 安装redis和beanstalkd,还可以通过swoole 添加定时器,以及进行多进程进行消费
#从仓库里将redis和beanstalkd下载
docker pull redis:5.0.7
docker pull schickling/beanstalkd
#查看镜像列表
docker images
#将beanstalkd运行在docker容器并映射到本地主机11300端口
docker run --name beanstalkd -d -it -p 11300:11300 428
docker run --name redis01 -d -it -p 6380:6379 redis:5.0.7
d:
cd D:\phpstudy_pro\WWW\test\beanstalkd
#安装
composer require pda/pheanstalk:3.1
composer require predis/predis:1.1
生产者
require "vendor/autoload.php";
use Pheanstalk\Pheanstalk;
try{
$p = new Pheanstalk('127.0.0.1',11300);
$data = [
'msg_id' => session_create_id(),
'tid' => time().uniqid()
];
// 当前的管道
$id = $p->putInTube('task',json_encode($data));
var_dump($id);
}catch (Exception $e){
}
消费者
require "vendor/autoload.php";
use Pheanstalk\Pheanstalk;
try{
$p = new Pheanstalk('127.0.0.1',11300);
$redis = new Predis\Client('tcp://127.0.0.1:6380');
while(1){
$job = $p->watch('task')->reserve();
if(!empty($job)){
$json = $job->getData();
$data = json_decode($json,true);
$state = $redis->get('job:'.$data['msg_id']);
if($state == 1){
echo '任务'.$data['msg_id'].'正在执行'. PHP_EOL;
$p->release($job,0,5);
continue;
}else if($state == 2){
echo '任务'.$data['msg_id'].'已经完成'. PHP_EOL;
continue;
}else{
echo '任务'.$data['msg_id'].'开始运行'. PHP_EOL;
$redis->setex('job:'.$data['msg_id'],6,1);
sleep(5);
$redis->set('job:'.$data['msg_id'],2);
//ack应答机制
$p->delete($job);
echo '5秒后,任务'.$data['msg_id'].'运行完成'. PHP_EOL;
}
}
}
}catch (Exception $e){
}