消息队列的概念、原理、实现方式是什么
Admin 2022-11-18 群英技术资讯 953 次浏览
这篇文章主要讲解了“消息队列的概念、原理、实现方式是什么”,文中的讲解内容简单、清晰、详细,对大家学习或是工作可能会有一定的帮助,希望大家阅读完这篇文章能有所收获。下面就请大家跟着小编的思路一起来学习一下吧。
架构设计1 采用定时任务的方式
php入门到就业线上直播课:进入学习
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API调试工具:点击使用
使用配送处理系统进行处理时,将当前数据库里需要处理的订单状态更新为2,待处理完成后将状态设为1
可以每次指定更新多少条数据
使用队列的数据结构
图示如下
代码流程如下
秒杀程序将请求写入redis(uid,time)
检查redis列表存放的长度,超过10个直接舍弃
通过死循环读取redis数据,并存入数据库
// Spike.php 秒杀程序if(Redis::llen('lottery') < 10){
// 成功
Redis::lpush('lottery', $uid.'%'.microtime());}else{
// 失败} 登录后复制 // Warehousing.php 入库程序while(true){
$user = Redis::rpop('lottery');
if (!$user || $user == 'nil') {
sleep(2);
continue;
}
$user_arr = explode($user, '%');
$insert_user = [
'uid' => $user_arr[0],
'time' => $user_arr[1]
];
$res = DB::table('lottery_queue')->insert($insert_user);
if (!$res) {
Redis::lpush('lottery', $user);
}} 登录后复制 上述代码中假如并发过大的话会存在超卖的情况,此时可以使用文件锁或者redis分布式锁进行控制,先将商品放入redis list中 使用rpop进行取出,如果取不到则说明已经卖完
具体的思路及伪代码如下
// 先将商品放入redis中
$goods_id = 2;
$sql = select id,num from goods where id = $goods_id;
$res = DB::select($sql);
if (!empty($res)) {
// 也可以指定多少件
Redis::del('lottery_goods' . $goods_id);
for($i=0;$i<$res['num'];$i++){
Redis::lpush('lottery_goods . $goods_id', $i);
}
LOG::info('商品存入队列成功,数量:' . Redis::llen('lottery_goods . $goods_id'));
} else {
LOG::info($goods_id . '加入失败');
} 登录后复制 // 开始秒杀
$count = Redis::rpop('lottery_goods' . $goods_id);
if (!$count) {
// 商品已抢完
...
}
// 用户抢购队列
$user_list = 'user_goods_id_' . $goods_id;
$user_status = Redis::sismember($user_list, $user_id);
if ($user_status) {
// 已抢过
...
}
// 将抢到的放到列表中
Redis::sadd($user_list, $uid);
$msg = '用户:' . $uid . '顺序' . $count;
Log::info($msg);
// 生成订单等
...
// 减库存
$sql = update goods set num = num -1 where id = $goods_id and num > 0; // 防止超卖
DB::update($sql)
// 抢购成功 登录后复制 架构及原理
其中P代表生产者,X为交换机(channal),C代表消费者
简单使用
// Send.php
require_once __DIR__.'/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
// 创建通道
$channel = $connection->channel();
// 声明一个队列
$channel->queue_declare('user_email', false, false, false, false);
// 制作消息
$msg = new AMQPMessage('send email');
// 将消息推送到队列
$channel->basic_publish($msg, '', 'user_email');
echo '[x] send email';
$channel->close();
$connection->close(); 登录后复制 // Receive.php
require_once __DIR__.'/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
//创建通道
$channel = $connection->channel();
$channel->queue_declare('user_email', false, false, false, false);
// 当收到消息时的回调函数
$callback = function($msg){
//发送邮件
echo 'Received '.$msg->body.'\n';
};
$channel->basic_consume('user_email', '', false, true, false, false, $callback);
// 保持监听状态
while($channel->is_open()){
$channel->wait();
}
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
PHP是在服务器端执行的脚本语言,是常用的网站编程语言。那么PHP的注释方法是什么呢?下面我们来详细了解PHP中注释的写法
php中__call方法的用法:1、当要调用的方法不存在或者权限不足时候,会自动调用。2、首先要重写__call方法,__call方法有2个参数,method和param,对应真实的方法名字和参数。
文本主要给大家分享的是关于PHP超级全局变量的内容,这篇主要介是几个常用PHP 超级全局变量,PHP $GLOBALS、PHP $_REQUEST、PHP $_POST和PHP $_GET,感兴趣的朋友就继续往下看吧。
php桥接模式的介绍:1、将两个原本不相关的类结合在一起,然后利用两个类中的方法和属性,输出一份新的结果。2、结构分为抽象类、被提炼的抽象类、实现类、具体实现类和客户端代码。
swoole使用纯C编写,不依赖其他第三方库;swoole并没有用libevent,所以不需要安装libevent;swoole并不依赖php的stream/sockets/pcntl/posix/sysvmsg等扩展。
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 ICP核准(ICP备案)粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008