美文网首页
单聊群聊,系统通知,状态同步,到底是推还是拉?

单聊群聊,系统通知,状态同步,到底是推还是拉?

作者: 枭龙gogogo | 来源:发表于2020-05-06 18:00 被阅读0次

系统通知

广义系统通知,有1对1的通知,以及一对多的通知,有相对实时的业务通知,以及能够容忍一定延时的系统通知。

系统对1的通知

典型业务,计数类通知:
  • 有10个美女添加了你为好友
  • 有8个好友私信了你
需要实时
  • 登录时拉取,增量推送
  • 一旦有消息丢失,网页端的计数会一直不一致
不需要实时
  • 只有在链接跳转,或者刷新网页时,才重新拉取最新的通知

系统对多的通知

弹窗新闻
需求
  • 同一天,用户登录弹出的新闻是相同的(很多业务符合这样的场景),不同天新闻则不一样(但所有用户都一样)
  • 每天第一次登录弹出新闻,当天的后续登录不出新闻
数据结构
  • 弹窗新闻表
    t_msg(msg_id, date, msg_content)
  • 用户信息表
    t_user(user_id, user_info, …)
  • 用户收到的新闻弹窗
    t_user_msg(user_id, msg_id, date)
推送
  • 将t_user_msg里对于所有user_id推送插入一个msg_id,表示未读
  • 在user每天第一次登录的时候,将当天的msg_id拉取出来,并删除,表示已读
  • 在user每天非第一次登录的时候,就拉取不到msg_id于是不会再次弹窗
拉取
  • 在user每天第一次登陆时,将当天的msg_id拉取出来,并插入t_user_msg,表示已读
  • 在user每天非第一次登陆时,则会插入t_user_msg失败,则说明已读
优化
  • 在t_user表加一列,表示用户最近拉取的弹窗时间
  • 在user每天第一次登录时,将当天的msg_id拉取出来,并将last_msg_date修改为今天
  • 在user每天非第一次登录时,发现last_msg_date为今天,则说明今天已读
弹窗广告
需求

-每天会对一批在线用户推送相同的弹窗广告

解决方案
  • for循环批量推送
  • keepalive请求拉取
  • 避免雪崩

状态同步

可简化为在线和离线两种状态

获取好友状态

uid-A登录

先去数据库拉取自己的好友列表,再去缓存获取所有好友的状态


登录拉取状态
好友状态改变时如何同步
拉取

向服务器轮询拉取全部好友的状态,例如每1分钟一次

  • 时延
  • 低效
推送

uid-B状态改变时(由登录、登出等动作触发),服务端不仅要在缓存中修改uid-B的状态,还要将这个状体改变的通知推送给uid-B的在线好友


状态推送
  • 优势:实时
  • 缺点:当在线好友量很大时,任何一个用户状态的改变,会扩散成N个实时通知,这个N叫做“消息风暴扩散系数”。假设一个IM系统平均每个用户有200个好友,平均有20%的好友在线,那么消息风暴扩散系数N=40,这意味着,任何一个状态的变化会变成40个推送请求。
群友状态改变时如何同步

假设平均每个用户加了20个群,平均每个群有200个用户,依然假设20%的用户在线,那么为了保证群友状态的实时性,每个用户登录,就要将自己的状态改变通知发送给2020020%=800个群友,N=800,意味着,任何一个状态的变化会变成800个推送请求。

  • 按需拉取,延时拉取:在真正进入一个群时才实时拉取群友的在线状态
总结
  • 好友状态同步,是采用推送的方式同步
  • 群友状态同步,由于消息风暴扩散系数过大,一般采用拉取的方式同步
  • 群友状态同步,还能采用按需拉取的优化方式,进一步降低服务端压力
  • “消息风暴扩散系数”是指一个消息发出时,变成N个消息的扩散系数,这个系数一定程度上决定了技术采用推送还是拉取

相关文章

网友评论

      本文标题:单聊群聊,系统通知,状态同步,到底是推还是拉?

      本文链接:https://www.haomeiwen.com/subject/wkonwhtx.html