docker + redis + beanstalkd + swoole to build a robust queue

Keywords: Programming Redis PHP Docker JSON

The technologies used are docker + redis + beanstalkd + swoole

#Download redis and beanstalkd from the warehouse
docker pull redis:5.0.7
docker pull schickling/beanstalkd
#View image list
docker images
#Running beanstalkd in the docker container and mapping to the local host port 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
#install
composer require pda/pheanstalk:3.1
composer require predis/predis:1.1
Bash
Copy
  performance Reliability (ack response) Extensibility
kafka 8w/s Unreliable colony
rabitMQ 4w/s reliable colony
redis 8w/s Unreliable colony
beanstalk 8w/s reliable Manual construction

beanstalkd is a high performance and lightweight memory queue system
beanstalkd feature
1. Support priority (support team to jump in line)
2. Delay (to achieve timed tasks)
3. Persistence (regularly brush the data in memory to the binlog log)
4. Reservation (set the task as reservation, the consumer cannot take out the task, and then take it out for processing at a proper time)
5. Task timeout resend (the consumer must process the task within the specified time, if not, the task will be deemed as failed and re entered the queue)
beanstalkd core elements
Producer - > tube - > job - > consumer

job: a task to be processed asynchronously needs to be placed in a tube
tube: a task queue with a name, used to store unified types of job s, and can create multiple channels
Producer: the producer of a job
Consumer: the consumer of a job

Process: the producer generates a task job, pushes the task job into a tube, and then the consumer takes the job out of the tube for execution

composer.json

"require":{
	"pda/pheanstalk":"^3.1",
	"predis/predis": "^1.1",
}

Producer generated task

<?php
//producer.php
require "vendor/autoload.php";

try{
	$p = new \Pheanstalk\Pheanstalk('127.0.0.1',11300);
	//Swoole? Timer? Tick timer
	swoole_timer_tick(10,function() use ($p)){
		$data = [
			'msg_id' => session_create_id(),//php7.1 new generated random id
			'tid'=>time().uniqid(),
		];
		$id = $p->putInTube('task',json_encode($data));//Put into pipeline
		var_dump($id);
	}

}catch(Exception $e){

}
PHP
Copy

Consumer performs tasks

<?php
//consumer.php
require "vendor/autoload.php";
//If it takes 5 seconds to execute a task, then it takes 50 seconds for 10 tasks. How to improve efficiency
//Get task data and execute business (multi process programming) according to task type
$workerNum = 5;
$pool = new Swoole\Process\Pool($workerNum);

//Process start up
$pool->on('WorderStart',function($pool,$workerId){
	echo 'Worder#'.$workderId.'is started';
	try{
		$p = new \Pheanstalk\Pheanstalk('127.0.0.1',11300);
		$redis = new Predis\Client('tcp://127.0.0.1:6380');
		//Remove task from pipeline
		//If there is no data, it will suspend waiting for data, so while will not enter the loop
		while(true){
			$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){//There are consumers in the process of implementation
					$p->release($job,0,5);//Delay the delivery task for 5 seconds
				}elseif($state == 2){//It's done
					continue;
				}else{
					//setex(key,seconds,value)
					$redis->setex('job:'.$data['msg_id'],6,1);
					//Do other operations such as sending SMS and adding points
					sleep(5);
					$redis->set('job:'.$data['msg_id'],2);
					//ack response mechanism is designed for message reliability
					$p->delete($job);
				}
			}
		}
	}catch(Exception $e){

	}
});
$pool->on('WorderStop',function($pool,$workerId){
	echo 'Worder#'.$workderId.'is stopped';
});
PHP
Copy

Posted by genix2011 on Fri, 10 Apr 2020 07:46:22 -0700