redis可以做消息队列吗
应用场景:
例如秒杀。瞬时大量写入订单到数据库,导致数据库无法及时响应。此时可以采用Redis做消息队列,把所有需要写入的数据先写入Redis消息队列中,然后同时在服务器开启php-cli进程循环读取队列中的数据,异步写入数据库。使用redis做消息队列可能会出现消息丢失的情况,因为没有消息接收的确认机制。大型程序,应该使用类似RabitMQ来做专业消息队列。
1、使用publish/subscribe方式作为消息队列
特点:一个消息发布者(生产者),可以对应多个消息订阅者(消费者)。当消息发布到消息队列的时候,所有消息订阅者都可以收到消息。适用于分布式消息分发。client以阻塞的方式等待publish端的消息。多个消费者不能加快消息消费速度。
消息生产:
$params =json_encode(['x_uid' => $x_uid, 'phone' => $phone]); $redis->publish('test',$params); //test表示发布的频道名字
消息消费(php-cli模式运行):
$redis = new Redis(); $redis->pconnect('127.0.0.1'); //必须用pconnect长连接 //设置redis连接永远不超时。默认60s超时断开连接 $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); $redis->subscribe(array('test'), 'callback'); //test表示频道名字,callback 回调函数名 functioncallback($redis, $chan, $msg){ //对收到的消息进行处理函数 $params = json_decode($msg,true); .... }
pconnect和connect区别:
connect:脚本结束之后连接就释放了。
pconnect:脚本结束之后连接不释放,连接保持在php-fpm进程中。
所以使用pconnect代替connect,可以减少频繁建立redis连接的消耗。
2、使用list作为redis消息队列
特点:一个消息生产者,对应一个消息消费者。多个消费者可以加快消息消费速度。
消息生产:
$redis =newRedis(); $redis->connect('127.0.0.1'); //将需要写入数据库的数据全部push到队列(复杂数据可以先json编码成字符串) $list = json_encode(['x_uid' => $x_uid, 'phone' => $phone, 'goods_id' => $goodsId, 'add_time' => time(), 'num_field' => $num_field]); $redis->lpush('winer',$list);
注意:brpop消费数据如果没有成功写入数据库,会导致数据丢失。强烈要求生产数据时,二次备份到redis或文件中。
消息消费(php-cli模式运行):
注意:MySQL不主动关闭连接的情况下,一次连接最长八小时后自动断开。
<?php //链接数据库 $conn = mysqli_connect("localhost","root","root"); if(!$conn){ die("连接数据库失败:". mysqli_error()); } mysqli_select_db($conn,"api"); //字符转换,读库 mysqli_query($conn,"set character set 'utf8'"); //写库 mysqli_query($conn,"set names 'utf8'"); //连接本地的 Redis 服务 $redis =newRedis(); $redis->connect('127.0.0.1',6379); //设置redis连接永远不超时。默认60s超时断开连接 $redis->setOption(Redis::OPT_READ_TIMEOUT,-1); echo 'Listening...'; $i =1; while(true){ $data = $redis->brpop('winer',0); // 0表示没有接收到参数的情况下,永远不超时断开 $info = json_decode($data[1],true); $x_uid = $info['x_uid']; $phone = $info['phone']; $goods_id = $info['goods_id']; $add_time = $info['add_time']; $num_field = $info['num_field']; //将数组写入数据库、订单 $sql = "insert into hd_hengda11_order (`x_uid`,`phone`,`goods_id`,`add_time`) values ($x_uid,$phone,$goods_id,$add_time)" $re = mysqli_query($conn,$sql); echo $i.'_ok||'; $i++; } ?>
其他:
秒杀场景防止商品超卖:
1、数据库中设置商品数量为无符号型,即不允许负数。当更新商品数量到负数时,返回false。
2、商品数量存在Redis的list队列中,每次抢购就pop删除一个元素出队列。
//存放商品数量的队列 for($j =1; $j <=10; $j++){ /设置商品数量为10 $re =Redis::lpush(gooods_count,1); }
判断商品数量逻辑
$count=Redis::lpop('gooods_count'); //$count = Redis::llen('gooods_count'); //llen判断队列长度 if(!$count){ return'已经抢光了哦'; }
更多Redis相关知识,请访问Redis使用教程栏目!
以上是redis可以做消息队列吗的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

本文解决了Redis版本的兼容性挑战。 主要版本升级由于命令,数据结构和配置的变化而引起的显着兼容性风险。 这篇文章强调使用Redis-CLI进行彻底的测试

本文详细介绍了通过命令行检查Redis服务器版本的方法。 主要方法Redis-CLI信息服务器有效地从服务器的输出中检索了版本信息,提供了直接可靠的解决方案。 替代a

本文讨论了在Redis群集中选择碎片键,并强调了它们对性能,可伸缩性和数据分布的影响。关键问题包括确保均匀数据分配,与访问模式保持一致以及避免常见错误l

本文详细介绍了检查Redis服务器版本的方法。 它使用Redis-CLI - Version和Info Server进行比较,检查配置文件,过程列表和软件包管理器。 redis-cli中的信息服务器命令被确定为t

本文详细介绍了Redis版本号,其字符串数据类型以及用于检查版本的方法(使用Redis-CLI,配置文件或编程方式)。 它还探讨了主要版本之间的差异,重点是增强性能

本文讨论了在REDIS中实施和管理缓存无效的策略,包括基于时间的到期,事件驱动的方法和版本控制。它还涵盖了缓存到期的最佳实践和监视和自动的工具

本文讨论了在REDIS中实施身份验证和授权,重点是实现身份验证,使用ACL以及确保REDIS的最佳实践。它还涵盖了管理用户权限和工具以增强重新安全性。
