Heim  >  Artikel  >  Datenbank  >  Kann Redis als Nachrichtenwarteschlange verwendet werden?

Kann Redis als Nachrichtenwarteschlange verwendet werden?

尚
Original
2019-07-05 15:31:483717Durchsuche

Kann Redis als Nachrichtenwarteschlange verwendet werden?

Anwendungsszenarien:

Zum Beispiel Flash-Sale. Eine große Anzahl von Bestellungen wird sofort in die Datenbank geschrieben, was dazu führt, dass die Datenbank nicht rechtzeitig antworten kann. Zu diesem Zeitpunkt können Sie Redis als Nachrichtenwarteschlange verwenden, alle Daten, die geschrieben werden müssen, zuerst in die Redis-Nachrichtenwarteschlange schreiben und dann den PHP-CLI-Prozess auf dem Server starten, um die Daten in der Warteschlange in einer Schleife zu lesen und schreiben Sie es asynchron in die Datenbank. Die Verwendung von Redis als Nachrichtenwarteschlange kann zum Verlust von Nachrichten führen, da es keinen Bestätigungsmechanismus für den Nachrichtenempfang gibt. Große Programme sollten so etwas wie RabitMQ als professionelle Nachrichtenwarteschlange verwenden.

1. Publish/Subscribe-Methode als Nachrichtenwarteschlange verwenden

Funktionen: Ein Nachrichtenherausgeber (Produzent) kann mehreren Nachrichtenabonnenten (Konsumenten) entsprechen. Wenn eine Nachricht in der Nachrichtenwarteschlange veröffentlicht wird, können alle Nachrichtenabonnenten die Nachricht empfangen. Geeignet für die verteilte Nachrichtenverteilung. Der Client wartet blockierend auf Nachrichten von der Veröffentlichungsseite. Mehrere Verbraucher können den Nachrichtenverbrauch nicht beschleunigen.

Nachrichtenproduktion:

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

Nachrichtenverbrauch (Betrieb im PHP-CLI-Modus):

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

Der Unterschied zwischen pconnect und connect:

connect: danach verbinden Das Skript endet. Es wurde veröffentlicht.

pconnect: Die Verbindung wird nach Beendigung des Skripts nicht freigegeben und die Verbindung verbleibt im PHP-FPM-Prozess.

Die Verwendung von pconnect anstelle von connect kann die Kosten für den häufigen Aufbau von Redis-Verbindungen senken.

2. Liste als Redis-Nachrichtenwarteschlange verwenden

Funktionen: Ein Nachrichtenproduzent entspricht einem Nachrichtenkonsumenten. Mehrere Verbraucher können den Nachrichtenverbrauch beschleunigen.

Nachrichtenerzeugung:

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

Hinweis: Wenn die brpop-Verbrauchsdaten nicht erfolgreich in die Datenbank geschrieben werden, kommt es zu Datenverlust. Wenn Produktionsdaten dringend benötigt werden, sollte eine sekundäre Sicherung auf Redis oder Dateien durchgeführt werden.

Nachrichtenverbrauch (Betrieb im PHP-CLI-Modus):

Hinweis: Wenn MySQL die Verbindung nicht aktiv schließt, wird eine Verbindung nach bis zu acht Stunden automatisch getrennt.

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

Sonstiges:

Flash-Sale-Szenario zur Verhinderung von Überverkäufen von Produkten:

1 Stellen Sie die Produktmenge in der Datenbank auf den Typ ohne Vorzeichen ein, d. h. negative Zahlen sind nicht vorhanden erlaubt. Wenn die Produktmenge auf eine negative Zahl aktualisiert wird, wird „false“ zurückgegeben.

2. Die Menge des Produkts wird in der Redis-Listenwarteschlange gespeichert. Bei jedem Ansturm wird ein Element aus der Warteschlange entfernt.

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

Logik zur Beurteilung der Produktmenge

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

Weitere Informationen zu Redis finden Sie in der Spalte Tutorial zur Redis-Nutzung!

Das obige ist der detaillierte Inhalt vonKann Redis als Nachrichtenwarteschlange verwendet werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn