Home >Database >Redis >Can redis be used as a message queue?

Can redis be used as a message queue?

尚
Original
2019-07-05 15:31:483943browse

Can redis be used as a message queue?

Application scenarios:

For example, flash sale. A large number of orders are written to the database instantly, causing the database to be unable to respond in time. At this time, you can use Redis as the message queue, write all the data that needs to be written to the Redis message queue first, and then start the php-cli process on the server to read the data in the queue in a loop and write it to the database asynchronously. Using redis as a message queue may cause message loss because there is no confirmation mechanism for message reception. Large programs should use something like RabitMQ as a professional message queue.

1. Use publish/subscribe method as message queue

Features: One message publisher (producer) can correspond to multiple message subscribers (consumers). When a message is published to the message queue, all message subscribers can receive the message. Suitable for distributed message distribution. The client waits for messages from the publish side in a blocking manner. Multiple consumers cannot speed up message consumption.

Message production:

$params =json_encode(['x_uid' => $x_uid, 'phone' => $phone]);
$redis->publish('test',$params); //test表示发布的频道名字

Message consumption (php-cli mode operation):

$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);
....
}

The difference between pconnect and connect:

connect: connect after the script ends It was released.

pconnect: The connection is not released after the script ends, and the connection remains in the php-fpm process.

So using pconnect instead of connect can reduce the consumption of frequently establishing redis connections.

2. Use list as redis message queue

Features: A message producer corresponds to a message consumer. Multiple consumers can speed up message consumption.

Message production:

$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);

Note: If brpop consumption data is not successfully written to the database, data loss will occur. When production data is strongly required, secondary backup should be done to redis or files.

Message consumption (php-cli mode operation):

Note: If MySQL does not actively close the connection, a connection will be automatically disconnected after up to eight hours.

<?php
//链接数据库
$conn = mysqli_connect("localhost","root","root");
if(!$conn){
die("连接数据库失败:". mysqli_error());
}
mysqli_select_db($conn,"api");
//字符转换,读库
mysqli_query($conn,"set character set &#39;utf8&#39;");
//写库
mysqli_query($conn,"set names &#39;utf8&#39;");
 
//连接本地的 Redis 服务
$redis =newRedis();
$redis->connect(&#39;127.0.0.1&#39;,6379);
//设置redis连接永远不超时。默认60s超时断开连接
$redis->setOption(Redis::OPT_READ_TIMEOUT,-1);
echo &#39;Listening...&#39;;
$i =1;
while(true){
$data = $redis->brpop(&#39;winer&#39;,0); // 0表示没有接收到参数的情况下,永远不超时断开
$info = json_decode($data[1],true);
$x_uid = $info[&#39;x_uid&#39;];
$phone = $info[&#39;phone&#39;];
$goods_id = $info[&#39;goods_id&#39;];
$add_time = $info[&#39;add_time&#39;];
$num_field = $info[&#39;num_field&#39;];
//将数组写入数据库、订单
$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.&#39;_ok||&#39;;
$i++;
}
?>

Others:

Flash sale scenarios to prevent oversold products:

1. Set the product quantity in the database to unsigned, that is, negative numbers are not allowed. When the item quantity is updated to a negative number, false is returned.

2. The quantity of the product is stored in the Redis list queue. Every time a rush is made, an element is popped out of the queue.

//存放商品数量的队列
for($j =1; $j <=10; $j++){ /设置商品数量为10
$re =Redis::lpush(gooods_count,1);
}

Judging product quantity logic

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

For more Redis related knowledge, please visit the Redis usage tutorial column!

The above is the detailed content of Can redis be used as a message queue?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn