企業(yè)檔案
- 會員類型:免費會員
- 工商認證: 【未認證】
- 最后認證時間:
- 法人:
- 注冊號:
- 企業(yè)類型:生產(chǎn)商
- 注冊資金:人民幣萬
聯(lián)系我們
聯(lián)系人:周潔
熱門標簽
技術文章
今日頭條極速版邀請碼是什么?邀請碼是怎么樣生成的?
點擊次數(shù):343 發(fā)布時間:2019/8/21 13:31:06
現(xiàn)在的互聯(lián)網(wǎng)公司推出新產(chǎn)品的時候,經(jīng)常使用邀請碼(DFZEQS4E)作為一種運營手段,在一定的時間內(nèi),只有具有邀請資格的用戶,才能參與到早期產(chǎn)品的體驗中去。
這么做,一方面為了體現(xiàn)產(chǎn)品體驗的稀缺性,鼓勵用戶搶購,造成供不應求的輿論影響。這點小米做的尤為突出,效果也是相當不錯的。另一方面,先讓一部分比較有熱情的早期種子用戶進來,也能夠充分的對產(chǎn)品的易用性和體驗流程進行早期的驗證,方便手機用戶的反饋之后迭代修改。·
我們首先來看看根據(jù)需求邀請碼服務需要提供出哪些接口:
單個或批量的生成邀請碼,要求六位,數(shù)字與字符的混合,供運營和用戶使用;
給用戶激活邀請碼;
校驗用戶是否已經(jīng)激活邀請碼;
批量給已注冊用戶綁定幾個可用的邀請碼,方便二次傳播;
查詢用戶名下已經(jīng)綁定的邀請碼和其被激活的情況,驗證二次傳播的效果
根據(jù)需求,現(xiàn)有的技術實現(xiàn)方案有很多,核心來講的話主要有兩點:
邀請碼生成算法與性保證
邀請碼高效查詢與激活
另外還有一些其他的點,會在文中慢慢道來。
邀請碼的生成方式
產(chǎn)品的要求是六位,同時字母和數(shù)字混合的方式,一共會發(fā)放10000個左右。一開始的思路是使用純算法的方式實現(xiàn),通過生成的ID,增加一些共性的信息,再根據(jù)信息摘要的方式,映射成字母與數(shù)字的混合,不過試了一下,算法實現(xiàn)的成本比較高,而且還有借助額外的ID生成的工具,所以有些得不償失。
另外由于不能是純數(shù)字,所以十六進制映射的方案也無法進行。而且也不能是一長串的字符,這樣md5的方案也無法實施了。
所以在這樣的前提之下,決定使用簡單算法+redis來做整個方案。
首先是邀請碼的生成,由于生成的過程一般是后臺或者手動觸發(fā),所以對性能的要求并不太高,也就是說,允許一定程度的碰撞。所謂的碰撞,就是算法算出來的邀請碼,和已經(jīng)生成的邀請碼重復了。所以我們來算一下概率:
一共是六位的邀請碼,每一位的組成是大小寫字母+阿拉伯數(shù)字,也就是26+26+10=62種可能性。所以六位也就是一共能夠產(chǎn)生出62^6=56,800,235,584即560億個邀請碼,產(chǎn)品的要求是一共放出去一萬個,所以即使現(xiàn)在已經(jīng)有一萬個邀請碼被生成了,那么生成一個邀請碼和現(xiàn)有邀請碼重復的概率只是10000/560億, 非常低的概率,如果真的中了大獎,那么就進行二次生成,再次碰撞的概率,恐怕就更低了。
同時為了保證邀請碼看起來更真實,再增加一個連續(xù)兩位不能重復的驗證,同時每次生成結(jié)束之后,使用redis驗證是否,即可實現(xiàn)整個邀請碼的生成過程。
數(shù)據(jù)結(jié)構(gòu)的設計
上文說到為了保證邀請碼的性,必須使用redis,redis中的集合數(shù)據(jù)結(jié)構(gòu)就提供了很好支持。每次生成完成后,只需要調(diào)用isMember validatorSet方法,即可根據(jù)返回判斷是否已經(jīng)生成了邀請碼。
同時使用集合存儲邀請碼,也能夠滿足統(tǒng)計的需求,只需要定時執(zhí)行smembers validatorSet,即可統(tǒng)計出所有生成出來的邀請碼。
另外,由于存在用戶激活邀請碼,和查詢是否已經(jīng)激活邀請碼的尋求,所以必須對此設計專門的數(shù)據(jù)結(jié)構(gòu)。查詢需求是高頻需求,在用戶量比較大的情況下,會有比較大的訪問壓力。同時為了擴展可能存儲的用戶其他信息,所以使用散列的數(shù)據(jù)類型進行存儲。
每次查詢用戶是否已經(jīng)激活,只需要執(zhí)行hget user:$guid validator 即可獲取其中的邀請碼信息,從而判斷出用戶是否已經(jīng)激活。
而用戶激活的過程,涉及的數(shù)據(jù)結(jié)構(gòu)稍多,每次激活的過程,都需要分成幾步:
步是查詢這個邀請碼是否是合法有效的邀請碼,需要使用ismember validatorSet進行判斷;
如果合法有效,第二步是設置用戶的激活狀態(tài),即上文中所用到的這個散列hset user:$guid validator {$validator};
第三步則是設置邀請碼本身的狀態(tài),即這個邀請碼被哪個用戶用了,方便之后查詢 set validator:{$validator}:status {'userName':ted,'avatar':'http://test.com'}
由于第二步和第三步必須保證數(shù)據(jù)的冪等性,因此需要使用redis的事務來進行執(zhí)行,保證兩者能夠同時成功的被執(zhí)行:
$redis->Multi()
->set validator:{$validator}:status {'userName':ted,'avatar':'http://test.com'}
->hset user:$guid validator {$validator}
->exec()
但是除了使用事務,還需要規(guī)避的就是兩個用戶同時取到了同一個邀請碼,在同一時間進行了激活的操作,在高并發(fā)的情況下,會有原子性的問題。所以必須引入redis中的watch命令,監(jiān)控邀請碼的status這個key,保證一旦它被變更了,那么當前的事務就不再執(zhí)行,從而避免給用戶帶來錯誤的反饋:
redis->watch validator:{$validator}:status
由此,就完成了用戶邀請碼的激活過程。
除此之外,還有個小功能,那就是給一批種子用戶綁定幾個邀請碼,并在邀請碼被激活之后,展示出相應的狀態(tài)。剛剛說到了用戶為維度的那個哈希表結(jié)構(gòu),是時候給它再加一個field了,這個field就叫boundValidators,專門用來存儲用戶名下被綁定的邀請碼:
hset user:$guid boundValidators $validator1|$validator2...
那么查詢的時候只需要進行兩次查詢:
// 查詢用戶名下綁定的邀請碼
hset user:$guid boundValidators
// 查詢邀請碼是否以及被誰激活了
mget $boundValidators
為了降低網(wǎng)絡延時,完全可以通過一個pipeline實現(xiàn),從而使得網(wǎng)絡交互從兩次變成一次。
接口性能驗證
由此已經(jīng)大功告成,簡單的使用wrk測試一下性能,服務器相比之前的差一些,一共是4核16G內(nèi)存。使用wrk -t12 -c100 -d10s http:ip:port/queryActivate,
海外內(nèi)網(wǎng)、同步的redis調(diào)用:
QPS在5000左右,完全滿足了本次邀請碼的需求,事實上,如果能超過這個量,估計睡覺都要笑醒了:)
原創(chuàng)作者:武漢醫(yī)建教育咨詢有限公司