成長計劃方案

1.  需求簡介算法

根據用戶的測試狀況,給他推薦相應的課程,而後根據學習時長能夠得到勳章數據庫

2.  效果圖緩存

 

3.  功能拆解異步

3.1.  測試題分佈式

【要點】學習

一、 須要一個題庫,配好題目和答案選項;測試

二、須要根據用戶的答題狀況(分數)抽取必定量的各類類型的題目大數據

三、本次抽取的題目與上一次的題目重複率不得超過50%spa

四、提交答案3d

【難點】

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

3.2.  生成計劃

【要點】

一、從大數據那裏獲取推薦內容

二、上一個計劃未完成不容許開啓下一個計劃

三、同種勳章只能得到一次

四、保存數據(計劃、計劃詳情、勳章、消息)

【難點】

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

二、考慮到重複提交的狀況,需加分佈式鎖

3.3.  計劃首頁

【要點】

一、內容展現,包括分已購未購、免費付費、會員非會員、標籤等等

二、學習時長展現,包括時長、天數、當前階段、勳章等等

【難點】

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

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

3.4.  學習時長

【要點】

一、實時記錄

【難點】

一、線上相似的接口高峯時段可達到1分鐘84萬次請求,所以想都不用想,必須異步,咱們採用MQ

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

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

四、學習時長是一個特別重要的參數,關係到挑戰任務,關係到勳章,所以以秒爲單位,累計至1分鐘再寫入

五、在壓測的時候,我發現基於Redis的分佈式鎖彷佛並不能保證徹底100%鎖住,雖然機率極低,但我好像碰到了

3.5.  樓層

【要點】

一、根據用戶計劃的狀態展現不一樣的按鈕及背景圖

二、連續關閉兩次樓層後再也不出現,新開啓計劃後再次出現

【難點】

一、用戶關閉樓層的行爲直接記到Redis中,沒必要存數據庫

3.6.  彈窗

【要點】

一、每一個挑戰任務對應一個勳章,再加上最後一個獎勵勳章。任務是有順序的,所以彈窗也是,爲此須要知道任務先後的關係

二、每一個彈窗只彈一次,所以須要記錄用戶是否查看過

【難點】

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

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

3.7.  通知消息

【要點】

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

二、不用的階段的消息文案不同

【難點】

一、定時任務掃描

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

4.  壓測

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

後來,加上了本地緩存Caffeine,感受快了不少

順便看下其它指標

相關文章
相關標籤/搜索