当前位置:网站首页>利用 rpush 和 blpop 实现 Redis 消息队列
利用 rpush 和 blpop 实现 Redis 消息队列
2022-08-03 19:46:00 【叶赫那拉 赫敏】
背景
系统并发比较强的业务中,为了解决并发问题,这个时候就会用到消息队列,异步处理业务。本次就介绍用rpush结合blpop实现Redis的消息队列方案之一。我们此次以取消订单业务为例子(取消订单无业务代码,重点介绍消息队列实现)。
方案介绍
利用redis命令rpush往redis列表尾部插入数据,之后利用blpop阻塞式从列表中获取列表做左边数据(先进先出),阻塞式获取数据是写在后端代码中,也就是消费队列数据的代码中。消费函数
consume(app/WorkQueue.php->consume())由定时任务每5分钟执行一次,在consume()代码中程序执行到290秒会自动结束,因为5分钟后定时任务下一个进程会再次调用
app/WorkQueue.php->consume()。
实现
目录总览
配置
app/config/config.php配置文件,quueDriver为存储的每个队列驱动,cancel_order为取消订单驱动,cancel_order下class值对应app/logic/ Order.php, app/WorkQueue.php->consume()会自动去根据配置到app/logic/下加载这个类;配置method为class对应的类中执行业务逻辑的方法;open代表是否开启此队列,true开启 false关闭,如果为false即使定时任务请求进来,也会中止程序不执行业务代码。
Redis相关
**redis key前缀:**我们使用QUEUE_
**redis队列值得数据方式:**采用json串;在app/WorkQueue.php->consume()中消费队列数据时会转为数组。
入列举例:
执行消费队列数据
消费函数consume(app/WorkQueue.php->consume())由定时任务每5分钟执行一次,在consume()代码中程序执行到290秒会自动结束,因为5分钟后定时任务下一个进程会再次调用app/WorkQueue.php->consume()
定时任务调用消费方法方式
php /app/WorkQueue.php 配置中驱动名称(app/config/config.php比如(cancel_order)
*/5 * * * * php /app/WorkQueue.php cancel_order
<?php
require_once './config/config.php';
class WorkQueue
{
/**
* 执行消息队列消费
*/
public function consume() {
$startTime = time();//程序开始时间
$allowAllExcuteTime = 290;//允许程序总执行时间,因为定时任务会5分钟执行一次,所以到290秒提前结束,因为下一个进程要进来
$configArr = include_once './config/config.php';//配置
$quueDriverConfig = $configArr['quueDriver'];//队列配置
$driverName = $argv[1];//获取定时任务命令传递的驱动名称 比如 php /home/www/app/WorkQueue.php cancel_order 那么此处就是cancelOrder
$redisQueueKey = "QUEUE_{$driverName}";//redis队列的前缀为QUEUE_
//获取队列驱动的logic任务类
$logicName = $quueDriverConfig[$driverName]['class'];
$method = $quueDriverConfig[$driverName]['method'];
//判断此队列驱动是否开启 如果未开启则不消费队列
if($quueDriverConfig[$driverName]['open'] !== true){
return;
}
//加载相应消息队列类
require_once "./logic/queue/{$logicName}.php";
$logicQueueObj = new $logicName();//实例化
$redis = new redis();//redis对象
$redis->connect('127.0.0.1', 6379);
//获取队列任务池列表
while (true) {
$specialTime = $allowAllExcuteTime - (time() - $startTime);//取得程序执行时间和290秒相比较,如果超过280秒直接break
if($specialTime <= 0){
break;
}
//获取任务池的一个任务
$content = $redis->BLPOP($redisQueueKey, $specialTime);//取出左边第一个值 如果没有则阻塞式监听;需要RPUSH入列
$contentArr = json_decode($content,true);
//执行任务
if (is_array($content)) {
$logicQueueObj->$method($contentArr);
}
}
}
}
//实例化类执行消费队列数据
$workQueueObj = new WorkQueue();
$workQueueObj->consume();
BLPOP阻塞式监听队列key $redisQueueKey,可以指定阻塞监听时间$specialTime,如果没有队列数据,会再阻塞监听$specialTime秒
$redis->BLPOP($redisQueueKey, $specialTime)
执行业务代码,$contentArr为队列数据
$logicQueueObj->$method($contentArr)
总结
队列实现方式有很多种,只要选择适合自己业务场景的即可!在实际业务处理中还会涉及到比如从队列取出数据,如果代码业务层处理业务失败,是否会将此队列数据重新压入队列的问题,这里只是稍微提一下。
边栏推荐
- matplotlib画polygon, circle
- 【统计机器学习】线性回归模型
- In-depth understanding of JVM-memory structure
- 开源生态研究与实践| ChinaOSC
- NNLM、RNNLM等语言模型 实现 下一单词预测(next-word prediction)
- Benchmarking Lane-changing Decision-making for Deep Reinforcement Learning
- LeetCode 952. 按公因数计算最大组件大小
- 高性能计算软件与开源生态| ChinaOSC
- Postgresql快照优化Globalvis新体系分析(性能大幅增强)
- 【木马免杀】
猜你喜欢
阿里巴巴政委体系-第五章、阿里政委体系建设
Anaconda 虚拟环境迁移
LeetCode 622. 设计循环队列
详解AST抽象语法树
List类的超详细解析!(超2w+字)
Statistical machine learning 】 【 linear regression model
友宏医疗与Actxa签署Pre-M Diabetes TM 战略合作协议
「游戏建模干货」建模大师几步操作,学习经典,赶紧脑补一下吧
Line the last time the JVM FullGC make didn't sleep all night, collapse
演讲议题及嘉宾重磅揭晓,TDengine 开发者大会推动数据技术“破局”
随机推荐
剑指 Offer II 044. 二叉树每层的最大值-dfs法
Unity获取canvas 下ui 在屏幕中的实际坐标
Standard C language learning summary 11
Statistical machine learning 】 【 linear regression model
建模该从哪一步开始?给你分析,给零基础的你一些学习建议
MySQL基础
Matlab论文插图绘制模板第42期—气泡矩阵图(相关系数矩阵图)
ctfshow php特性
标准C语言学习总结11
php根据两点经纬度计算距离
149. The largest number on a straight line, and check the set
relocation R_X86_64_PC32 against,/usr/bin/ld: final link failed: Bad value
力扣刷题之求两数之和
1161 最大层内元素和——Leetcode天天刷【BFS】(2022.7.31)
LeetCode 952. Calculate Maximum Component Size by Common Factor
(十六)51单片机——红外遥控
Detailed AST abstract syntax tree
Solution for no navigation bar after Word is saved as PDF
Postgresql源码(65)新快照体系Globalvis工作原理分析
glide set gif start stop