系統(tǒng)通知
廣義系統(tǒng)通知,有1對(duì)1的通知般妙,以及一對(duì)多的通知纪铺,有相對(duì)實(shí)時(shí)的業(yè)務(wù)通知,以及能夠容忍一定延時(shí)的系統(tǒng)通知碟渺。
系統(tǒng)對(duì)1的通知
典型業(yè)務(wù)鲜锚,計(jì)數(shù)類通知:
- 有10個(gè)美女添加了你為好友
- 有8個(gè)好友私信了你
需要實(shí)時(shí)
- 登錄時(shí)拉取,增量推送
- 一旦有消息丟失苫拍,網(wǎng)頁端的計(jì)數(shù)會(huì)一直不一致
不需要實(shí)時(shí)
- 只有在鏈接跳轉(zhuǎn)芜繁,或者刷新網(wǎng)頁時(shí),才重新拉取最新的通知
系統(tǒng)對(duì)多的通知
彈窗新聞
需求
- 同一天绒极,用戶登錄彈出的新聞是相同的(很多業(yè)務(wù)符合這樣的場景)骏令,不同天新聞則不一樣(但所有用戶都一樣)
- 每天第一次登錄彈出新聞,當(dāng)天的后續(xù)登錄不出新聞
數(shù)據(jù)結(jié)構(gòu)
- 彈窗新聞表
t_msg(msg_id, date, msg_content) - 用戶信息表
t_user(user_id, user_info, …) - 用戶收到的新聞彈窗
t_user_msg(user_id, msg_id, date)
推送
- 將t_user_msg里對(duì)于所有user_id推送插入一個(gè)msg_id垄提,表示未讀
- 在user每天第一次登錄的時(shí)候榔袋,將當(dāng)天的msg_id拉取出來周拐,并刪除,表示已讀
- 在user每天非第一次登錄的時(shí)候凰兑,就拉取不到msg_id于是不會(huì)再次彈窗
拉取
- 在user每天第一次登陸時(shí)妥粟,將當(dāng)天的msg_id拉取出來,并插入t_user_msg吏够,表示已讀
- 在user每天非第一次登陸時(shí)勾给,則會(huì)插入t_user_msg失敗,則說明已讀
優(yōu)化
- 在t_user表加一列稿饰,表示用戶最近拉取的彈窗時(shí)間
- 在user每天第一次登錄時(shí)锦秒,將當(dāng)天的msg_id拉取出來露泊,并將last_msg_date修改為今天
- 在user每天非第一次登錄時(shí)喉镰,發(fā)現(xiàn)last_msg_date為今天,則說明今天已讀
彈窗廣告
需求
-每天會(huì)對(duì)一批在線用戶推送相同的彈窗廣告
解決方案
- for循環(huán)批量推送
- keepalive請(qǐng)求拉取
- 避免雪崩
狀態(tài)同步
可簡化為在線和離線兩種狀態(tài)
獲取好友狀態(tài)
uid-A登錄
先去數(shù)據(jù)庫拉取自己的好友列表惭笑,再去緩存獲取所有好友的狀態(tài)
好友狀態(tài)改變時(shí)如何同步
拉取
向服務(wù)器輪詢拉取全部好友的狀態(tài)侣姆,例如每1分鐘一次
- 時(shí)延
- 低效
推送
uid-B狀態(tài)改變時(shí)(由登錄、登出等動(dòng)作觸發(fā))沉噩,服務(wù)端不僅要在緩存中修改uid-B的狀態(tài)捺宗,還要將這個(gè)狀體改變的通知推送給uid-B的在線好友
- 優(yōu)勢:實(shí)時(shí)
- 缺點(diǎn):當(dāng)在線好友量很大時(shí),任何一個(gè)用戶狀態(tài)的改變川蒙,會(huì)擴(kuò)散成N個(gè)實(shí)時(shí)通知蚜厉,這個(gè)N叫做“消息風(fēng)暴擴(kuò)散系數(shù)”。假設(shè)一個(gè)IM系統(tǒng)平均每個(gè)用戶有200個(gè)好友畜眨,平均有20%的好友在線昼牛,那么消息風(fēng)暴擴(kuò)散系數(shù)N=40,這意味著康聂,任何一個(gè)狀態(tài)的變化會(huì)變成40個(gè)推送請(qǐng)求贰健。
群友狀態(tài)改變時(shí)如何同步
假設(shè)平均每個(gè)用戶加了20個(gè)群,平均每個(gè)群有200個(gè)用戶恬汁,依然假設(shè)20%的用戶在線伶椿,那么為了保證群友狀態(tài)的實(shí)時(shí)性,每個(gè)用戶登錄氓侧,就要將自己的狀態(tài)改變通知發(fā)送給2020020%=800個(gè)群友脊另,N=800,意味著约巷,任何一個(gè)狀態(tài)的變化會(huì)變成800個(gè)推送請(qǐng)求偎痛。
- 按需拉取,延時(shí)拉仍赝ァ:在真正進(jìn)入一個(gè)群時(shí)才實(shí)時(shí)拉取群友的在線狀態(tài)
總結(jié)
- 好友狀態(tài)同步看彼,是采用推送的方式同步
- 群友狀態(tài)同步廊佩,由于消息風(fēng)暴擴(kuò)散系數(shù)過大,一般采用拉取的方式同步
- 群友狀態(tài)同步靖榕,還能采用按需拉取的優(yōu)化方式标锄,進(jìn)一步降低服務(wù)端壓力
- “消息風(fēng)暴擴(kuò)散系數(shù)”是指一個(gè)消息發(fā)出時(shí)御吞,變成N個(gè)消息的擴(kuò)散系數(shù)竖幔,這個(gè)系數(shù)一定程度上決定了技術(shù)采用推送還是拉取