成長計划方案


1.  需求簡介

根據用戶的測試情況,給他推薦相應的課程,然后根據學習時長可以獲得勛章

2.  效果圖

 

3.  功能拆解

3.1.  測試題

【要點】

1、 需要一個題庫,配好題目和答案選項;

2、需要根據用戶的答題情況(分數)抽取一定量的各種類型的題目

3、本次抽取的題目與上一次的題目重復率不得超過50%

4、提交答案

【難點】

這個功能最復雜的地方在於重復率不得超過50%,可以用兩次的題目去交集來判斷,也可以排除上一次的題目后再隨機,沒有用什么高深的算法(主要是不懂)這里我用的后者,不再贅述。

3.2.  生成計划

【要點】

1、從大數據那里獲取推薦內容

2、上一個計划未完成不允許開啟下一個計划

3、同種勛章只能獲得一次

4、保存數據(計划、計划詳情、勛章、消息)

【難點】

1、調大數據的接口時要考慮到失敗的情況,即使大數據的服務掛了,咱們也不能掛,為此加上try...catch,超時時間等等都是必要,這還不夠。萬一調大數據失敗了,返回保底數據。

2、考慮到重復提交的情況,需加分布式鎖

3.3.  計划首頁

【要點】

1、內容展示,包括分已購未購、免費付費、會員非會員、標簽等等

2、學習時長展示,包括時長、天數、當前階段、勛章等等

【難點】

1、查數據庫想都不要想,首選直接查Redis,但是Redis查的次數多了綜合起來也有可能慢,必要時可考慮本地緩存(內存緩存)

2、時長、天數等均從在Redis總累計,可直接獲取

3.4.  學習時長

【要點】

1、實時記錄

【難點】

1、線上類似的接口高峰時段可達到1分鍾84萬次請求,因此想都不用想,必須異步,我們采用MQ

2、盡管消費者是一條一條的消費,然而這並不意味着一秒鍾只消費一條,據觀察,線上其它類似MQ消費者平均一秒鍾消費300條

3、時長最終是要更新到MySQL數據庫中的,但是如此頻繁的寫數據,風險比較大,想來想去,最終選擇用定時任務在夜深人靜的時候從Redis同步到MySQL

4、學習時長是一個特別重要的參數,關系到挑戰任務,關系到勛章,因此以秒為單位,累計至1分鍾再寫入

5、在壓測的時候,我發現基於Redis的分布式鎖似乎並不能保證完全100%鎖住,雖然概率極低,但我好像碰到了

3.5.  樓層

【要點】

1、根據用戶計划的狀態展示不同的按鈕及背景圖

2、連續關閉兩次樓層后不再出現,新開啟計划后再次出現

【難點】

1、用戶關閉樓層的行為直接記到Redis中,不必存數據庫

3.6.  彈窗

【要點】

1、每個挑戰任務對應一個勛章,再加上最后一個獎勵勛章。任務是有順序的,因此彈窗也是,為此需要知道任務前后的關系

2、每個彈窗只彈一次,因此需要記錄用戶是否查看過

【難點】

1、用雙向鏈表將挑戰任務串聯起來,這樣就可以根據當前所處階段快速找到上一個或下一個任務

2、在Redis緩存結構上,我犯了一個錯誤。原因我想的是既然是有順序的要不就用List類型,但是后來發現更新的時候極其不方便,要把所有的元素先刪除(LTRIM命令),然后修改后重新插入,在一次壓測過程中發現里面大量重復數據,還沒刪完就已經插入了,於是越插入越多,這就是偷懶的代價,最終緊急改成Hash類型,這樣即使有重復也會被覆蓋。

3.7.  通知消息

【要點】

1、APP消息和站內信都要發

2、不用的階段的消息文案不一樣

【難點】

1、定時任務掃描

2、異步發送,保證互不影響

4.  壓測

所有的Redis查詢都是批量查詢,即使是這樣,響應時間依然很長,平均響應時間400ms左右。用PinPoint分析排查:

后來,加上了本地緩存Caffeine,感覺快了很多

順便看下其它指標

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM