redis能不能用来做消息队列

58次阅读
没有评论

共计 2451 个字符,预计需要花费 7 分钟才能阅读完成。

自动写代码机器人,免费开通

这篇文章主要介绍了 redis 能不能用来做消息队列,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让丸趣 TV 小编带着大家一起了解一下。

应用场景:

例如秒杀。瞬时大量写入订单到数据库,导致数据库无法及时响应。此时可以采用 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 $j++){ / 设置商品数量为 10
$re =Redis::lpush(gooods_count,1);
}

判断商品数量逻辑

$count=Redis::lpop( gooods_count 
//$count = Redis::llen( gooods_count //llen 判断队列长度
if(!$count){return 已经抢光了哦}

感谢你能够认真阅读完这篇文章,希望丸趣 TV 小编分享 redis 能不能用来做消息队列内容对大家有帮助,同时也希望大家多多支持丸趣 TV,关注丸趣 TV 行业资讯频道,遇到问题就找丸趣 TV,详细的解决方法等着你来学习!

向 AI 问一下细节

丸趣 TV 网 – 提供最优质的资源集合!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2024-02-03发表,共计2451字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)