天天看點

抽獎實作方式

具體步驟:

1、我們是根據使用者積分抽獎的,每5積分抽一次,每天限制最多抽獎5次。(積分擷取方式:每天簽到擷取積分,做任務贈積分)

2、使用者通路抽獎頁面,有個大轉盤,使用者點選大轉盤中間按鈕,開始通路背景

3、前台必須往背景傳送jwt字元串,背景校驗jwt字元串并解析出使用者資訊,根據使用者id判斷使用者積分是否足夠抽獎

4、如果使用者沒能力抽獎,告訴使用者積分不足,給個連結讓使用者掙積分

5、如果使用者有能力抽獎,判斷使用者今天抽了幾次獎,如果超過5次,提示使用者今天抽獎次數已用完

6、如果使用者可以繼續抽獎,使用mq往抽獎微服務發送一個抽獎請求

7、抽獎微服務需要接收到使用者的id和時間戳,從redis當中擷取資料,判斷是第幾個使用者在抽獎,如果是30000次在抽獎送小米手機一部,如果是50000次在抽獎送聯想手機,如果是第70000次抽獎送蘋果手機。

8、如果是其它次數抽獎,送3、5、10積分不等。這裡涉及到一個獎池初始化的操作

redis獎池的設計:

通過redis的

BoundListOperations

這個類用于存放積分獎品,第一次抽獎先初始化獎池,建立一個list,裡面存放28000個1積分,20000個3積分,16000個5積分,6000個10積分,使用

Collections.shuffle

這個方法把list裡存放值的順序打散,再把打散後的獎品放到BoundListOperations這個redis棧中,然後從棧最左邊取出一個值傳回給使用者。

第一次初始好獎池後,下面再進來抽獎的使用者判斷BoundListOperations中有沒有值,就初始化一個獎池,獎池的獎品是7萬個積分獎品。

如果有值就從BoundListOperations的最左側抽出一個值,這個值取出後BoundListOperations就會減掉這個值,這個目的是為了讓獎品不重複。

抽到的獎品如何傳回:

抽到的獎品放入到redis當中,key是以lottery+userid+時間戳組成的,目的是為了确定獎品的唯一性,因為一個使用者一天抽5次獎,如果不給使用者id加時間戳,那使用者抽中同一個獎就會覆寫上次抽獎。抽獎微服務執行完畢。

回到抽獎的方法中,發送mq之後,傳回到前台,

前台是個while循環,循環5次,循環中有個sleep睡眠,一秒執行一次通路背景一個抽獎結果方法,目的是為了讓一秒中往redis中擷取一次資料,看看抽獎微服務是否執行完成,如果redis在5秒内能夠查詢到資料,說明抽獎微服務執行完成,并往資料庫中插入一條資料,讓目前使用者的抽獎次數加1,再給使用者傳回抽獎結果。前台大轉盤拿到這個獎品以後,把轉盤指針指向獎品的位置,并提醒使用者您抽到了什麼獎,使用者點選進入個人中心,就可以看到獎品記錄了。

1、前台抽獎系統講解

如何獲得抽獎機會?

使用者每次充值會員獲得5次抽獎機會,

每答題一次獲得三次抽獎機會

每天簽到獲得一次抽獎機會

抽獎機會可以累加,但每天抽獎次數限制三次

每次抽獎耗費5積分

抽獎送課程大禮包。

每天簽到送積分(話術)

使用者在個人中心點選簽到按鈕,送5積分,每個使用者隻能簽到一次,每次根據簽到的日期狀态判斷,隻要使用者今天簽到過一次,就不允許再簽到了,這個使用者每次點選簽到時在背景判斷。這個狀态存入到redis當中

抽獎完成後如何給使用者郵寄過去?

如果是電商的話本身就對接了快遞公司,讓使用者填寫郵寄位址即可。

如果是線上教育類的送課程大禮包,就直接兌換成課程。

如果既不是兌換課程,又不是電商平台,那就直接在個人中心做個抽中獎品的頁面連接配接按鈕,點選那個按鈕,到中獎頁面,讓使用者填寫個人資訊和位址,郵寄過去,郵寄後隻需要在那個頁面顯示正在郵寄中就行了。

抽獎子產品是如何做的?

你重點說下你們的抽獎算法是如何寫的?

通過redis的BoundListOperations這個類用于存放積分獎品,第一次抽獎先初始化獎池,建立一個list,裡面存放28000個1積分,20000個3積分,16000個5積分,6000個10積分,使用Collections.shuffle這個方法把list裡存放值的順序打散,再把打散後的獎品放到BoundListOperations這個redis棧中,然後從棧最左邊取出一個值傳回給使用者。

第一次初始好獎池後,下面再進來抽獎的使用者判斷BoundListOperations中有沒有值,就初始化一個獎池,獎池的獎品是7萬個積分獎品。

如果有值就從BoundListOperations的最左側抽出一個值,這個值取出後BoundListOperations就會減掉這個值,這個目的是為了讓獎品不重複。

你們代碼中沒用到線程鎖嗎?

用到了,判斷使用者有能力抽獎以下代碼,發送mq之前加了線程鎖,讓使用者進行排隊執行發送mq消息。

如果我們想給員工做一個抽獎系統,我們要讓百分之20的人抽中三等獎,百分之15的人抽中二等獎,百分之5的人抽中一等獎,你這個獎池應該怎麼做?

很簡單,背景代碼把獎品數量寫死,然後用shuffle打散就可以了。比如一百個人,5個人一等獎,就寫個list放一等獎的值,15個二等獎,就寫個list放15個二等獎的值,最後打散,以此類推。

你們是如何防止高并發抽獎的,如何防止同一個使用者抽中獎

我們用了mq去處理,抽獎服務每次隻能接受一個使用者請求資料抽獎,其它使用者都會在mq中排隊,隻有第一個抽完放入redis後,第二個才能進來抽獎。

你們抽獎管理加mq那樣做不會影響性能嗎?并發來的時候怎麼辦?

不影響性能,我們項目目前最高承受并發是一千一百多(這個數自己說,隻要不超過一千五就行),一點問題都沒有,我們隻有十幾萬使用者,并沒有那麼大使用者量,處理并發也不是在一台機器上優化,我們也搭建了3台叢集處理,一台了可接受一千五左右,三台就是4千多。

你們獎池前台是如何做防刷的?背景是如何做防刷的?如果别人做個循環就是刷你的産品,你怎麼處理?

前台不需要做防刷,我們背景有判斷呀,判斷使用者積分夠不夠和今天是否抽獎次數到三次,這兩個條件判斷的,如果他在做刷獎操作,最起碼使用者根據使用者id判斷這關就過不了。

如果對方擷取了你使用者中所有的id,亂刷呢?

第一,他擷取所有使用者id刷獎品無意義,因為說不定哪個使用者擷取了獎品,又不會到暴力亂刷者手中。

第二,使用者抽中獎後,我們會先人工确認抽獎情況,然後再進行發貨。

第三,如果真要防止亂刷,可以檢測IP,如果有IP短時間内高速通路就用redis記錄下,半小時内不允許它通路。

如何做獎池管理?比如多個地區組成一個區,華北、華南、華東、華西四個區,四個區裡都有小獎池,最後又有一個統一的大獎池,如果要用獎池管理你怎麼思考的?

這得需要先建立一個最大獎池,然後通過大獎池随機給其它區的小獎池分發獎品,就如同抽獎一樣,整個過程都是随機的,比如大獎池生成了3個一等獎,6個二等獎,四個區分,肯定有一個區沒有一等獎,兩個區隻有一個二等獎,整體靠大獎池做總管理分發。

你們第幾次抽什麼獎是固定好的對吧?你們為什麼要固定某個數量抽到某個獎,你們如何考慮的?

這個可以随意設定的,想讓固定就固定,不固定也可以,如果不固定第多少個人來了抽中某個獎品,那這個獎品抽中就不可控了,具體為什麼選在10萬、15萬等數才能抽中獎,是根據我們使用者量來決定的,比如我們活躍使用者有3萬個,抽獎時間是三天,如果設定的比較靠前,一天就抽中了,那就沒意義了。(注意這個抽獎數、抽獎天數幾天、活躍使用者數自己想,不要按我的來,我隻是給思路)

你們内部員工也可以去抽的對吧?那員工抽中怎麼辦?

當然可以,我們沒做限制。如果員工抽中就給員工了,沒限制的。

你們對抽獎次數有限制嗎?你們抽獎周期有多長時間呢?

抽獎次數一天三次。抽獎周期為(3天、1周、1月、3月都可以),比如抽課程大禮包就是1-3個月比較好。

你們是如何防止多個使用者抽獎的時候并發問題的?如何防止多個使用者同時抽中一個獎品?

我們在抽獎時用到了mq,這樣就能夠很好的給mq進行排隊執行,防止使用者并發抽中同一個獎品。我們目前可承受并發是1千多,整體速度還是可以的,如果有問題可以加叢集處理。

上一篇: 橋模式 Bridge
下一篇: 安裝npm cnpm

繼續閱讀