中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

秒殺踩坑記:庫存超賣

發布時間:2020-07-10 03:49:01 來源:網絡 閱讀:1705 作者:hgditren 欄目:軟件技術
本案例發生在別人身上,覺得有學習借鑒的意義特轉載過來記錄一下。

PM 說有一個類似于搶購的小需求,我們第一反應就想到是典型的防止庫存超賣場景,于是理所因當地選用了 Redis 方案。只要保證是原子操作,即可防止庫存超賣,自然想到使用 Incr/Decr 這類原子操作。

查看 PHP 的 Redis 擴展關于 Incr 方法的說明:

/**
 * Increment the number stored at key by one.
 *
 * @param   string $key
 * @return  int    the new value
 * @link    http://redis.io/commands/incr
 *      
 */
public function incr( $key ) {}

可見,Incr 方法返回的是 key 操作后的新值,即 ++1 后的值,于是我們寫出了如下代碼:

$num = $redis->incr($key);
if ($num < $max) {
    //入搶購成功隊列,異步去執行搶購成功邏輯
} else {
    //不好意思呢,已經被搶完了
}

不知道你有沒有聞到這段代碼的壞味道,在大部分情況下會如你所想地運行,但是特殊場景下會 出現判斷失效 的邏輯問題,例如:

1、key 由于某些原因失效了;
2、Incr 操作失敗了,不會拋異常并返回 false;

上述兩種情況,都會導致$num < $max條件成立,進而導致更嚴重的邏輯問題,最終超賣。

問題描述與分析

我們就搶購開始后就遇到了上述的第二種情況,下面描述整個過程。先通過 Cat 監控平臺觀察到訪問量急劇上升,開始擔心應用服務坑不住,隨后日志平臺報警 Incr 操作存在異常幾率,再然后就出現超賣情況,緊急情況只能關閉業務開關。是什么原因導致判斷條件成立?

通過日志定位到 Incr 操作問題,便 Telnet 連接到線上 Redis 服務,發現了異常情況:

\# 查看值
GET key
100
# 嘗試修改
INCR key
READONLY You can't write against a read only slave

INFO
# Replication
role:slave

可以看出來,該連接的機器目前處于從機狀態,不可寫操作,所以 Incr 操作返回 false,同時 PHP 不同類型比較會存在隱式轉化,所以false < $num恒成立,導致計數器失效。而這一切又是由于 Redis 高可用不完善,當主從切換后,VIP 未能成功漂移,這部分是運維的鍋,研發代碼不夠健壯,這鍋同樣要背 >﹏<。

優化方案

首先,修改代碼使其更加健壯,增加計數器容錯處理:

$num = $redis->incr($key);
if ($num > 0 && $num < $max) {
    //入搶購成功隊列,異步去執行搶購成功邏輯
} else {
    //不好意思呢,已經被搶完了
}

然后,切換 Redis 源到高可用集群(Codis),測試并重新上線,第二日的搶購已經正常,看著 Cat 上流量逐漸平穩,心里也踏實了。

查看來源

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

福安市| 谢通门县| 呼伦贝尔市| 永兴县| 清原| 江津市| 邹平县| 阿鲁科尔沁旗| 锦屏县| 揭阳市| 鸡东县| 双流县| 秭归县| 大方县| 喀喇沁旗| 高要市| 哈尔滨市| 东莞市| 盈江县| 微博| 东乡县| 弥勒县| 文登市| 滁州市| 汉中市| 呼玛县| 资溪县| 烟台市| 柘城县| 延津县| 宁津县| 涟水县| 兰州市| 贵南县| 云阳县| 定州市| 梁平县| 平乡县| 社旗县| 通海县| 固安县|