二、微信搶紅包實現(xiàn)原理2.1 業(yè)務(wù)流程分析


2.2 功能拆解

2.2.1 新建紅包

在" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運營 > Redis秒殺實戰(zhàn):微信搶紅包(附源碼)

Redis秒殺實戰(zhàn):微信搶紅包(附源碼)

時間:2023-05-18 09:03:02 | 來源:網(wǎng)站運營

時間:2023-05-18 09:03:02 來源:網(wǎng)站運營

Redis秒殺實戰(zhàn):微信搶紅包(附源碼):

一、導讀

為啥寫這個微信搶紅包項目呢,公司 0202 年 08 月 22 日,公司周年慶,搶了100多紅包 ,O(∩_∩)O哈哈~

二、微信搶紅包實現(xiàn)原理

2.1 業(yè)務(wù)流程分析


2.2 功能拆解


2.2.1 新建紅包

在 DB、Redis 分別新增一條記錄

2.2.2 搶紅包(并發(fā))

請求Redis,紅包剩余個數(shù),大于0才可以拆,等會0時,提示用戶,紅包已搶完

2.2.3. 拆紅包(并發(fā))

「用到技術(shù)」

Redis 中數(shù)據(jù)類型的 String 特性的原子遞減(DECR key)和減少指定值(DECRBY key decrement)

「業(yè)務(wù)」

  1. 請求 Redis ,當剩余紅包個數(shù)大于 0,紅包個數(shù)原子遞減,隨機獲取紅包
  2. 計算金額,當最后一個紅包時,最后一個紅包金額=總金額-總已搶紅包金額
  3. 更新數(shù)據(jù)庫
2.2.4. 查看紅包記錄

查詢 DB 即可

2.3 數(shù)據(jù)庫設(shè)計

紅包流水表

CREATE TABLE `red_packet_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `red_packet_id` bigint(11) NOT NULL DEFAULT 0 COMMENT '紅包id,?timestamp+5位隨機數(shù)', `total_amount` int(11) NOT NULL DEFAULT 0 COMMENT '紅包總?,單位分', `total_packet` int(11) NOT NULL DEFAULT 0 COMMENT '紅包總個數(shù)', `remaining_amount` int(11) NOT NULL DEFAULT 0 COMMENT '剩余紅包?單位', `remaining_packet` int(11) NOT NULL DEFAULT 0 COMMENT '剩余紅包個數(shù)', `uid` int(20) NOT NULL DEFAULT 0 COMMENT '新建紅包?戶的?戶標識', `create_time` timestamp COMMENT '創(chuàng)建時間', `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATECURRENT_TIMESTAMP COMMENT '更新時間', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='紅包信息,新建?個紅包插??條記錄';紅包記錄表

CREATE TABLE `red_packet_record` ( `id` int(11) NOT NULL AUTO_INCREMENT, `amount` int(11) NOT NULL DEFAULT '0' COMMENT '搶到紅包的?', `nick_name` varchar(32) NOT NULL DEFAULT '0' COMMENT '搶到紅包的?戶的?', `img_url` varchar(255) NOT NULL DEFAULT '0' COMMENT '搶到紅包的?戶的頭像', `uid` int(20) NOT NULL DEFAULT '0' COMMENT '搶到紅包?戶的?戶標識', `red_packet_id` bigint(11) NOT NULL DEFAULT '0' COMMENT '紅包id?timestamp+5位隨機數(shù)', `create_time` timestamp COMMENT '創(chuàng)建時間', `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATECURRENT_TIMESTAMP COMMENT '更新時間', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='搶紅包記錄表,?個紅包插??條記錄';2.4 發(fā)紅包 API

發(fā)紅包接口開發(fā)

?往db中就單純存入一條記錄,Service層和Mapper層,就簡單的一條sql語句,主要是提供思路,下面會附案例源碼,不要慌
?
2.5 搶紅包 API

搶紅包算法拆解

通過上圖算法得出,靠前面的人,手氣最佳幾率小,手氣最佳,往往在后面

  1. 發(fā) 100 元,共 10 個紅包,那么平均值是 10 元一個,那么發(fā)出來的紅包金額在 0.01~20 元之間波動
  2. 當前面 4 個紅包總共被領(lǐng)了 30 元時,剩下 70 元,總共 6 個紅包,那么這 6 個紅包的金額在 0.01~23.3 元之間波動
搶紅包接口開發(fā)

2.6 測試

2.6.1. 發(fā)紅包

2.6.2 模擬高并發(fā)搶紅包(Jmeter壓測工具)

因為我發(fā)了 10 個紅包,金額是 20000,使用壓測工具,模擬50個請求,只允許前10個請求能搶到紅包,并且金額等于20000。

三、布隆過濾器(重要)

3.1 介紹

布隆過濾器是1970年由布隆提出的。它實際上是一個很長的二進制向量和一系列隨機映射函數(shù)。布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優(yōu)點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識別率和刪除困難。

3.1.1 優(yōu)點

相比于其他的數(shù)據(jù)結(jié)構(gòu),布隆過濾器在空間和時間方面都有巨大的優(yōu)勢。布隆過濾器存儲空間和插入/查詢時間都是常數(shù)。另外三列函數(shù)相互之間沒有關(guān)系,方便由硬件并行實現(xiàn)。布隆過濾器不需要存儲元素本身,在某些對保密要求非常嚴格的場合有優(yōu)勢。

3.1.2 缺點

但是布隆過濾器的缺點和有點一樣明顯。誤算率是其中之一。隨著存入的元素數(shù)量增加,誤算率隨之增加。但是如果元素數(shù)量太少,則使用散列表足矣。

3.2 布隆過濾器有什么用

  1. 黑客流量攻擊:故意訪問不存在的數(shù)據(jù),導致查程序不斷訪問DB的數(shù)據(jù)
  2. 黑客安全阻截:當黑客訪問不存在的緩存時迅速返回避免緩存及DB掛掉
  3. 網(wǎng)頁爬蟲對 URL 的去重,避免爬取相同的URL地址
  4. 反垃圾郵件,從數(shù)十億個垃圾郵件列表中判斷某郵件是否垃圾郵件(同理,垃圾短信)
  5. 緩存擊穿,將已存在的緩存放到布隆中,當黑客訪問不存在的緩存時迅速返回避免緩存及 DB 掛掉

四、布隆過濾器實現(xiàn)會員轉(zhuǎn)盤抽獎

4.1. 需求

一個抽獎程序,只針對會員用戶有效

4.2 通過google布隆過濾器存儲會員數(shù)據(jù)

  1. 程序啟動時將數(shù)據(jù)放入內(nèi)存中
  2. google自動創(chuàng)建布隆過濾器
  3. 用戶ID進來之后判斷是否是會員
4.3 代碼實現(xiàn)

4.3.1 引入依賴

<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>29.0-jre</version></dependency>4.3.2 數(shù)據(jù)庫會員表

CREATE TABLE `sys_user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `user_name` varchar(11) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '?戶名', `image` varchar(11) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '?戶頭像', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;4.3.3 初始化布隆過濾器

dao 層和 dao 映射文件,就單純的一個 sql 查詢,看核心方法,下面會附源碼滴,不要慌好嘛

4.3.4 控制層

4.3.5 測試

4.4 缺點

  1. 內(nèi)存級別產(chǎn)部
  2. 重啟即失效
  3. 本地內(nèi)存無法用在分布式場景
  4. 不支持大數(shù)據(jù)量存儲

五、Redis布隆過濾器

5.1 優(yōu)點

  1. 可擴展性 Bloom 過濾器
  2. 不存在重啟即失效或定時任務(wù)維護的成本
5.2 缺點

  1. 需要網(wǎng)絡(luò)IO,性能比基于內(nèi)存的過濾器低
5.3 布隆過濾器安裝

5.3.1. 下載

github:https://github.com/RedisBloom/RedisBloom

鏈接: https://pan.baidu.com/s/16DlKLm8WGFzGkoPpy8y4Aw
密碼: 25w1
5.3.2. 編譯

make

5.3.3 將 Rebloom 加載到 Redis 中

先把 Redis 給停掉?。?!在 redis.conf 里面添加一行命令->加載模塊

loadmodule /usr/soft/RedisBloom-2.2.4/redisbloom.so5.3.4 測試布隆過濾器

六、SpringBoot 整合 Redis 布隆過濾器

6.1 編寫兩個lua腳本

  1. 添加數(shù)據(jù)到指定名稱的布隆過濾器
  2. 從指定名稱的布隆過濾器獲取key是否存在的腳本
local bloomName = KEYS[1]local value = KEYS[2]--bloomFilterlocal result_1 = redis.call('BF.ADD',bloomName,value)return result_1local bloomName = KEYS[1]local value = KEYS[2]--bloomFilterlocal result_1 = redis.call('BF.EXISTS',bloomName,value)return result_16.2 在 RedisService.java 中添加 2 個方法

6.3 驗證

七、秒殺系統(tǒng)設(shè)計

7.1 秒殺業(yè)務(wù)流程圖

7.2 數(shù)據(jù)落地存儲方案

  1. 通過分布式redis減庫存
  2. DB存最終訂單信息數(shù)據(jù)
7.3 API性能調(diào)優(yōu)

  1. 性能瓶頸在高并發(fā)秒殺
  2. 技術(shù)難題在于超賣問題
7.4 實現(xiàn)步驟

提前將秒殺數(shù)據(jù)緩存到 redis

set skuId_start_1 0_1554045087 --秒殺標識set skuId_access_1 12000 --允許搶購數(shù)set skuId_count_1 0 --搶購計數(shù)set skuId_booked_1 0 --真實秒殺數(shù)
  1. 秒殺開始前,skuId_start為0,代表活動未開始
  2. 當skuId_start改為1時,活動開始,開始秒殺叭
  3. 當接受下單數(shù)達到sku_count*1.2后,繼續(xù)攔截所有請求,商品剩余數(shù)量為0(為啥接受搶購數(shù)為1萬2呢,看業(yè)務(wù)流程圖,涉及到“校驗訂單信息”,一般設(shè)置的值要比總數(shù)多一點,多多少自己定)
利用 Redis 緩存加速增庫存數(shù)

"skuId_booked":10000 //從0開始累加秒殺的個數(shù)只能加到1萬將用戶訂單數(shù)據(jù)寫入 MQ(異步方式)。

另外一臺服務(wù)器監(jiān)聽 mq,將訂單信息寫入到 DB。

好了,以上就是完整的開發(fā)步驟,下面我們開始編寫代碼

7.5 代碼實戰(zhàn)

7.5.1. 網(wǎng)關(guān)瀏覽攔截層

1、先判斷秒殺是否已經(jīng)開始

2、利用 Redis 緩存 incr 攔截流量

7.5.2. 訂單信息校驗層

1、校驗當前用戶是否已經(jīng)買過這個商品

2、校驗通過直接返回搶購成功

7.5.3 開發(fā)lua腳本實現(xiàn)庫存扣除

1、庫存扣除成功,獲取當前最新庫存

2、如果庫存大于0,即馬上進行庫存扣除,并且訪問搶購成功給用戶

3、考慮原子性問題

4、返回搶購結(jié)果

控制層

Service 層

布隆過濾器

7.6 初始化redis緩存

set skuId_start_1 0_1554045087 --秒殺標識set skuId_access_1 12000 --允許搶購數(shù)set skuId_count_1 0 --搶購計數(shù)set skuId_booked_1 0 --真實秒殺數(shù)7.7 秒殺驗證

jmeter 配置

壓測秒殺驗證原子性

八、項目下載

鏈接(奶牛 快傳): https://cowtransfer.com/s/74998eaf64da44
取件碼: rqzbyj

九、尾聲

演示的時候,我使用的 Redis 單機的,吞吐量不是很大,感興趣的,可以自己搭建個 Redis 主從復制+哨兵+集群,然后再測試。

最近比較忙,沒時間完善微信搶紅包秒殺的原子性。下面那個完整案例搶庫存的,親自使用 Jmeter 壓測幾次,是原子性的,可以拿來借鑒,感興趣的同學,可以借鑒下面搶庫存的代碼,把微信搶紅包的功能在完善下,我就不修改啦。

作者:陳彥斌
鏈接:https://www.cnblogs.com/chenyanbin/p/13587508.html
來源:博客園

關(guān)鍵詞:實戰(zhàn)

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關(guān)閉