說明:普通紅包是指金額每份金額固定的紅包包括群普通紅包和個人普通紅包
1 需求分析
一個字:錢
1.1用戶為什么要發(fā)紅包?
(1)逗別人玩自己開心
有些人發(fā)一些1分錢的紅包
(2)成為焦點人物
當(dāng)你經(jīng)常在群里發(fā)紅包的時候,你就會成為「群明星」
(3)獲得關(guān)注賣廣告
單純發(fā)一個廣告不但沒有人看
(4)純粹是一種祝福
有時候是我們產(chǎn)品經(jīng)理想太多了
1.2 用戶為什么要搶紅包
?
(1)好玩刺激
這個理由還是留給那些無聊的人
,不解釋,跟『為什么要發(fā)紅包?』的第一點差不多。那個【最佳手氣】,就刺激了人們玩紅包接龍(不是某寶那個坑爹的紅包接龍…)(2)貪婪——人類原始的欲望
在法律和道德重重的壓制下
(3)炫耀
證明自己單身20年
,哦!不對,應(yīng)該是證明自己手速快(不都是一個意思嘛,廢話真多!)有的人無聊到自己發(fā)自己搶,以此在炫耀自己的4G網(wǎng)絡(luò)、光纖還有…麒麟臂。(4)減少損失
很多人發(fā)了拼手氣紅包覺得自己錢包大出血
,于是自己又搶了一把,希望自己搶到大一點的金額,相當(dāng)于發(fā)少一點紅包。1.3 為什么要曬紅包
?
(1)炫富心理——我發(fā)出的紅包統(tǒng)計頁面
(2)攀比心理——紅包結(jié)果頁面
這里就不多作解釋了
,想想你為什么喜歡在朋友圈發(fā)東西就懂了。2 入口
1
入口主要分為兩大類:聊天窗口和微信錢包
。2
2.1錢包
在錢包添加紅包入口,是因為用戶首次使用時
,一般是先收到別人的紅包,自己要取錢,那么去哪里取呢?肯定是錢包,錢包需要集合所有跟錢有關(guān)的概念,給用戶一個深刻的印象,類似于OmniFocis的透視功能(不知道就算了…)3
2.2 聊天窗口
而這聊天窗口中加入紅包入口則是更加簡單粗暴,用戶在過年或者平常使用會經(jīng)常點開"+"發(fā)送圖片
,這就很容易會見到紅包入口了,而且微信在過年的時候特意把紅包按鈕用紅色高亮顯示了,這就更加容易被用戶發(fā)現(xiàn),從而提高入口轉(zhuǎn)換率。這里還有個邏輯,在單聊和群聊所進(jìn)入的紅包頁面的不同的,如下圖所示:4
群紅包默認(rèn)為拼手氣群紅包而不是定額紅包
,為什么要醬紫呢?先看看拼手氣群紅包的優(yōu)勢:1
、金額隨機(jī),時大時小的金額能給用戶驚喜;2
、可以看到其他用戶搶了多少,引起攀比心理(這次搶得不爽,下次一定要搶個大大噠);3
4
至于拼手氣群紅包相對于普通紅包的劣勢就是需要大量的計算資源去計算紅包的隨機(jī)金額
2.3 搖一搖
微信在春節(jié)前還額外的增加了搖一搖的紅包入口,給一直被認(rèn)為"約炮神器"的搖一搖洗白(哈哈
3 界面
3.1發(fā)紅包頁面
在單人聊天窗口進(jìn)入的普通(定向)紅包的頁面只需要輸入紅包金額和祝福語
5
這里不得不提的是一個非常人性化的設(shè)計
3.2紅包『搶』頁面
聊天窗口會顯示出紅包樣式的聊天消息
6
3.3紅包『拆』頁面
點擊按鈕【拆】之后,那坨黃色的東西會轉(zhuǎn)(用幾幀圖片切換形成的動畫
一是微信慣用的犧牲客戶端資源(CPU
二是以往基于web的紅包頁面經(jīng)常會出現(xiàn)"媽的頁面還在loading紅包就沒了""紅包來了卻連不了網(wǎng)是怎樣一種體驗"等等的用戶抱怨
7
那這四個頁面分別會在什么時候出現(xiàn)呢
?在5.2中會做詳細(xì)的介紹。3.4紅包結(jié)果頁面
紅包結(jié)果頁面會顯示搶到紅包的人的列表,其中金額最大的為手氣最佳
8
3.5搖一搖紅包
9
搖一搖紅包和企業(yè)紅包的隨機(jī)方法和群手氣紅包大同小異,由于沒有接觸過企業(yè)紅包的發(fā)放流程
為什么要有剩余紅包個數(shù)呢?
引用鵬飛在人人都是產(chǎn)品經(jīng)理舉辦的產(chǎn)品經(jīng)理大會廣州站上說的一句話"給用戶一個預(yù)期
上圖最后那個頁面你沒見過?
微信官方說
,當(dāng)服務(wù)器壓力過大的時候,喚起讓用戶休息一下這個頁面。這里我提出另外一種策略,也許微信也采用了這種策略:當(dāng)用戶搖一搖請求紅包時,服務(wù)器壓力過大,網(wǎng)絡(luò)阻塞或者隊列已滿等異常情況下,會直接通知客戶端"你沒有搶到",也就是直接返回那個搖紅包的頁面進(jìn)行下一次的搖一搖動作4后臺
4.1數(shù)據(jù)庫
以下關(guān)系型數(shù)據(jù)庫設(shè)計的字段是基于少量請求下,我們模擬紅包系統(tǒng)的可行方案
(1)用戶信息數(shù)據(jù)表user_info
userID、紅包ID
、祝福語、紅包類型、紅包個數(shù)、紅包金額、超時(2)用戶錢包數(shù)據(jù)表user_wallet
userID
、money、銀行卡ID等其他字段(3)發(fā)送紅包數(shù)據(jù)表red_send
紅包ID
、senderID、紅包個數(shù)、紅包金額、祝福語、最佳手氣、發(fā)出時間(4)接收紅包數(shù)據(jù)表red_receive
紅包ID、receiver
、接收時間、接收金額4.2隨機(jī)算法
很多人說紅包序列是預(yù)先在手機(jī)發(fā)出去的時候已經(jīng)產(chǎn)生好隨機(jī)序列,其實這樣會產(chǎn)生大量的數(shù)據(jù)庫讀寫操作
,內(nèi)存讀的速度以DDR3-2400為例,能達(dá)到17G/s,寫的速度達(dá)到18G/s(參考文獻(xiàn):http://m.it168.com/article_1410707_p5.html)。而硬盤數(shù)據(jù)庫的讀寫速度最多達(dá)到133MB/s?div id="4qifd00" class="flower right">以紅包ID為種子
>>>red_ID = 1775509988475009
>>>random.seed(red_ID)
群手氣紅包的最小值為0.01,搖一搖紅包的最小值為2.00
>>>min = 1.00
>>>if (紅包為群手氣紅包):
min = 0.01
else(紅包為搖一搖紅包):
min = 2.00
群手氣紅包的最大值為剩余紅包總額和個數(shù)的商的2倍(你可以在群里不停地發(fā)紅包做回歸
,記得叫上我去拿紅包,哈哈)。>>>max = (remain_money/remain_num)*2
而搖一搖紅包官方給出的計算公式是剩余金額/剩余紅包數(shù)*n
n主觀猜測也是等于2
,在這公司基礎(chǔ)上再人為控制概率。方案一:
人為干擾概率的
,有人拿到京東618元的紅包,動腦子想想,京東店慶是618,這個金額絕對不是隨機(jī)出來的,而是設(shè)定好金額,然后每個金額范圍都有一定的概率。比如說2元—5元概率為85%;5元—20元概率為10%
>>>a = random.uniform(0,1)
>>>b,_max,_min = 0
>>>if a < 0.85:
_min = 2.00
_max = 5.00
>>>elif a < 0.95 & a >= 0.85:
_min = 5.00
_max = 20.00
>>>elif a < 0.9999 & a >= 0.95:
_min = 20.00
_max = 50.00
>>>elif a > 0.9999:
_min = 618.00
_max = 618.00
>>>random.uniform(min,max)
方案二:
_min = 2.00
_max = 剩余金額/剩余紅包數(shù)*n
人為放出618元的彩蛋紅包
4.3紅包發(fā)出去那一刻發(fā)生了什么?
這一部分由于個人的水平限制
(1)發(fā)紅包后臺操作:
在數(shù)據(jù)庫中增加一條紅包記錄
在Cache(可能是騰訊內(nèi)部kv數(shù)據(jù)庫,基于內(nèi)存
(2)搶紅包后臺操作:
搶紅包分為搶和拆,搶操作在Cache層完成
拆紅包在數(shù)據(jù)庫完成
4.4 Q&A若干整理(這一部分是網(wǎng)上整理的
①既然在搶的時候有原子減了就不應(yīng)該出現(xiàn)搶到了拆開沒有的情況?
這里的原子減并不是真正意義上的原子操作
②cache和db掛了怎么辦
主備 +對賬
③有沒有紅包個數(shù)沒了
沒有,程序最后會有一個take all操作以及一個異步對賬保障
④為什么要分離搶和拆
總思路是設(shè)置多層過濾網(wǎng),層層篩選
⑤搶到紅包后再發(fā)紅包或者提現(xiàn),這里有什么策略嗎
大額優(yōu)先入賬策略
⑥有沒有從數(shù)據(jù)上證明每個紅包的概率是不是均等
不是絕對均等,就是一個簡單的拍腦袋算法
⑦發(fā)紅包人的錢會不會凍結(jié)
是直接實時扣掉
⑧采用實時算出金額是出于什么考慮
實時效率更高,預(yù)算才效率低下
⑨實時性:為什么明明搶到紅包,點開后發(fā)現(xiàn)沒有
答:2014年的紅包一點開就知道金額
2015年的紅包的拆和搶是分離的
,需要點兩次,因此會出現(xiàn)搶到紅包了,但點開后告知紅包已經(jīng)被領(lǐng)完的狀況。進(jìn)入到第一個頁面不代表搶到,只表示當(dāng)時紅包還有。詳見本文Jinkey在第五部分的說明⑩紅包的設(shè)計
答:微信從財付通拉取金額數(shù)據(jù)過來,生成個數(shù)/紅包類型/金額放到redis集群里
?并發(fā)性處理:紅包如何計算被搶完
答:cache會抵抗無效請求
?如何保持8w每秒的寫入
答:多主sharding
,水平擴(kuò)展機(jī)器。?查詢紅包分配,壓力大不
?答:搶到紅包的人數(shù)和紅包都在一條cache記錄上,沒有太大的查詢壓力
。?一個紅包一個隊列?
答:沒有隊列
,一個紅包一條數(shù)據(jù),數(shù)據(jù)上有一個計數(shù)器字段。?每領(lǐng)一個紅包就更新數(shù)據(jù)么?
答:每搶到一個紅包
,就cas更新剩余金額和紅包個數(shù)。?紅包如何入庫入賬
?數(shù)據(jù)庫會累加已經(jīng)領(lǐng)取的個數(shù)與金額
,插入一條領(lǐng)取記錄。入賬則是后臺異步操作。?入帳出錯怎么辦?比如紅包個數(shù)沒了
,但余額還有?答:最后會有一個take all操作。另外還有一個對賬來保障
。5交互
5.1前后端交互時序
(1)綁定銀行卡
10
(2)收發(fā)群手氣紅包
11
① 發(fā)起紅包操作
② 銀行扣款邏輯,不成功則返回
,成功則進(jìn)行下一步③ 請求將紅包寫入數(shù)據(jù)庫某個set
,并獲取紅包ID返回客戶端④ 長連接通知客戶端成功
⑤ 其他用戶接收到紅包消息,點開
⑥ 紅包結(jié)果會寫入LIstView(安卓的UI控件名稱
,ios也有類似的控件)中,用戶可以馬上看到⑦ 當(dāng)用戶再次打開紅包結(jié)果頁面時
,會從數(shù)據(jù)庫讀取最新的結(jié)果列表并更新結(jié)果列表。(3)收發(fā)普通紅包
① 發(fā)起紅包操作
② 銀行扣款邏輯
,不成功則返回,成功則進(jìn)行下一步③ 選擇發(fā)送對象(若在聊天窗口中發(fā)起著跳過這一步)
④ 計算紅包均值(總額/個數(shù))
,將紅包個數(shù)和均值寫入數(shù)據(jù)庫,返回紅包ID到客戶端⑤ 其他用戶點開紅包
,拆,訪問紅包個數(shù)判斷是否大于0,若為TRUE,則個數(shù)減1;若為FALSE則通知客戶端顯示【已領(lǐng)完】樣式。5.2 界面交互
5.2.1 基本流程
13
5.2.2 拆紅包頁面顯示邏輯
對群手氣紅包
、群普通紅包、普通紅包(其實就是紅包個數(shù)為1的群普通紅包)和是否領(lǐng)到和是否領(lǐng)完做3×3×3的交叉分析之后,歸納出以下結(jié)論:mmexport1442151693886
5.2.3 紅包結(jié)果頁面顯示邏輯
說明:
1 代表有出現(xiàn)該項
"字樣"代表下圖所示區(qū)域的文字內(nèi)容:
16
"按鈕"代表藍(lán)色文字鏈接,如下圖所示:
17
金額是指自己拿到的金額
18
搶到的人是指一個列表:
19
綠色格子代表沒有這種邏輯
,可能是不出現(xiàn)該頁面或者其他原因。對上表的數(shù)據(jù)進(jìn)行挖掘,我們可以發(fā)現(xiàn)以下規(guī)則集:
(1)當(dāng)領(lǐng)到紅包的時候
(2)當(dāng)自己發(fā)的紅包沒被領(lǐng)完
(3)領(lǐng)到別人發(fā)的紅包時
(4)對于群手氣紅包被領(lǐng)完時
,如果紅包是自己發(fā)的會顯示字樣"n個紅包共n元,n秒被搶光";如果是被人發(fā)的紅包則會顯示字樣"n個紅包,n秒被搶光";對于(群)普通紅包被領(lǐng)完時,會顯示字樣"n個紅包共n元";(5)對于紅包(個數(shù)大于1)沒被領(lǐng)完,自己的紅包會顯示字樣"已領(lǐng)取x/y個
,共x/y元";別人發(fā)的紅包字樣"領(lǐng)取x/y個";(6)對于紅包(個數(shù)等于1)沒領(lǐng)完時
,會顯示字樣"紅包金額n元,等待對方領(lǐng)取";(7)對于群手氣紅包和自己發(fā)的普通紅包都會顯示搶到紅包的人的列表
;(8)已經(jīng)被領(lǐng)完的群手氣紅包才會顯示"最佳手氣"的標(biāo)識;
從(4)-(6)的規(guī)則我們可以看出
5.2.4搖一搖紅包
這一部分因為寫文章的時候搖一搖紅包活動已經(jīng)下線了
僅以此文
僅剩5份