Maison >base de données >Redis >Redis peut-il être utilisé comme file d'attente de messages ?

Redis peut-il être utilisé comme file d'attente de messages ?

尚
original
2019-07-05 15:31:483942parcourir

Redis peut-il être utilisé comme file d'attente de messages ?

Scénarios d'application :

Par exemple, vente flash. Un grand nombre de commandes sont écrites instantanément dans la base de données, ce qui empêche la base de données de répondre à temps. À ce stade, vous pouvez utiliser Redis comme file d'attente de messages, écrire d'abord toutes les données qui doivent être écrites dans la file d'attente de messages Redis, puis démarrer le processus php-cli sur le serveur pour lire les données dans la file d'attente en boucle. et écrivez-le dans la base de données de manière asynchrone. L'utilisation de Redis comme file d'attente de messages peut entraîner une perte de messages car il n'existe aucun mécanisme de confirmation pour la réception des messages. Les grands programmes devraient utiliser quelque chose comme RabitMQ comme file d'attente de messages professionnelle.

1. Utiliser la méthode de publication/abonnement comme file d'attente de messages

Caractéristiques : Un éditeur de message (producteur) peut correspondre à plusieurs abonnés de message (consommateurs). Lorsqu'un message est publié dans la file d'attente des messages, tous les abonnés au message peuvent recevoir le message. Convient à la distribution de messages distribués. Le client attend les messages du côté publication de manière bloquante. Plusieurs consommateurs ne peuvent pas accélérer la consommation des messages.

Production de messages :

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

Consommation de messages (fonctionnement en mode 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);
....
}

La différence entre pconnect et connect :

connect : se connecter après le script se termine. Il a été publié.

pconnect : La connexion n'est pas libérée après la fin du script et la connexion reste dans le processus php-fpm.

Ainsi, utiliser pconnect au lieu de connect peut réduire le coût de l'établissement fréquent de connexions Redis.

2. Utiliser la liste comme file d'attente de messages Redis

Caractéristiques : Un producteur de message correspond à un consommateur de message. Plusieurs consommateurs peuvent accélérer la consommation des messages.

Production de messages :

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

Remarque : Si les données de consommation de brpop ne sont pas écrites avec succès dans la base de données, une perte de données se produira. Lorsque les données de production sont fortement requises, une sauvegarde secondaire doit être effectuée sur Redis ou sur des fichiers.

Consommation de messages (fonctionnement en mode php-cli) :

Remarque : Si MySQL ne ferme pas activement la connexion, une connexion sera automatiquement déconnectée après huit heures maximum.

<?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++;
}
?>

Autres :

Scénario de vente flash pour éviter les produits en survente :

1. Définissez la quantité de produit dans la base de données sur non signé, c'est-à-dire que les nombres négatifs ne sont pas autorisés. Lorsque la quantité de produit est mise à jour vers un nombre négatif, false est renvoyé.

2. La quantité du produit est stockée dans la file d'attente de la liste Redis. Chaque fois qu'un rush est effectué, un élément est retiré de la file d'attente.

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

Logique pour juger la quantité de produit

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

Pour plus de connaissances sur Redis, veuillez visiter la colonne Tutoriel d'utilisation de Redis !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn