Bei einigen E-Commerce-Websites mit einer bestimmten Anzahl von Benutzern ist der Druck auf die Datenbank sehr groß, wenn sie einfach relationale Datenbanken (wie MySQL, Oracle) für Eilkäufe verwenden, und wenn der Datenbanksperrmechanismus nicht verwendet wird Nun, es wird auch zum Problem überverkaufter Produkte und Gutscheine führen. Das gleiche Problem trat auch bei meinem Unternehmen auf, als das Problem auftrat. Da ich häufig Redis verwende, habe ich vor, dieses Problem zu lösen . Nutzen Sie die Hochleistungs- und Transaktionsfunktionen von Redis, um das Problem zu lösen, dass Online-Gutscheine durch Überbestände aufgebraucht werden. Nachfolgend gebe ich die erste Version des Pseudocodes an, mit dem ich dieses Problem vorübergehend gelöst habe, indem ich einige Details entfernte:
/** * 抢优惠券(秒杀) * @param int $couponId 商品ID * @param int $uid 用户ID * @return bool */ function secKill($couponId, $uid) { //1.初始化Redis连接 $redis = new Redis(); if (!$redis->connect('127.0.0.1', 6379)) { trigger_error('Redis连接出错!!!', E_USER_ERROR); } else { echo '连接正常<br>'; } //秒杀商品的库存key $key = 'secKill:'.$couponId.':stock'; $redis->watch($key); //获取库存 $stock = $redis->get($key); //秒杀未开始,表示库存为null if (!$stock && !is_numeric($stock)) { echo '秒杀未开始'; return false; } //判断库存,如果库存大于0,则减库存,将该成功秒杀用户加入哈希表,如果小于等于0,秒杀结束 if ($stock <= 0) { echo '秒杀已结束'; return false; } //用户已经成功秒杀过一次了,不允许再次参与秒杀 if ($redis->sIsMember('secKill:'.$couponId.':uid', $uid)) { echo '秒杀失败'; return false; } //代码走到这里,说明该用户是第一次参与秒杀,将库存减一,然后把这个人放到已抢到的集合表 $redisMulti = $redis->multi(); $redisMulti->decr($key); $redisMulti->sAdd('secKill:'.$couponId.':uid', $uid); $result = $redisMulti->exec(); if (empty($result)) {//事务被取消 echo '秒杀失败'; return false; } //抢券成功,将优惠券ID和UID放入到队列中,由一个单独的进程队列来消费队列里的数据,向用户推送抢到的优惠券 $redis->lPush('couponOrder', $couponId.'+'.$uid); return true; } $couponId = 11211; $uid = mt_rand(1, 100); secKill($couponId, $uid);
Zuerst habe ich simuliert Setzen Sie den Coupon-Bestand mit der Coupon-ID 11211 auf 10.
Dann verwenden wir das AB-Tool, um 1000 Anfragen und 50 Parallelität zum Testen zu simulieren.
ab -n 1000 -c 50 www.test.com/Und die verbleibende Anzahl an Coupons ist ebenfalls 0, also keine negative Zahl mehr Gleichzeitig werden auch die UID-Informationen von 10 Benutzern in der Benutzercoupon-Sammlung gespeichert. Der obige Code löst zwei Probleme:
Es löst das Problem einer großen Anzahl sofortiger Abfragen an die Datenbank, was einen großen Druck auf die Datenbank ausübt. Der Datenverkehr wird in der Redis-Cache-Ebene abgefangen
Tipps: Wenn der Coupon in der Verbrauchswarteschlange nicht ausgestellt wird, notieren Sie ihn unbedingt sofort und benachrichtigen Sie den Betriebsleiter per SMS, um zu prüfen, ob er erneut gesendet oder manuell im Hintergrund an den Benutzer weitergeleitet werden kann.
Das obige ist der detaillierte Inhalt vonSo lösen Sie mit PHP+Redis das Problem des Überverkaufs von Produkten bei hoher Parallelität. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!