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

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

作者: 枭龙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