https://mp.weixin.qq.com/s/KB1zdKcsh4PXXuJh4xb_Zw

网页端收消息,究竟是推还是拉?

原创 58沈剑 架构师之路 2020-12-28
 
https://mp.weixin.qq.com/s/kQlvuNO_VfeC7kzdWbQEQg

QQ好友状态,QQ群友状态,究竟是推还是拉?

原创 58沈剑 架构师之路 2020-12-21
状态同步,有好友状态的同步,有群友状态的同步,有的需要实时同步,有的能够容忍延时。任何脱离业务的架构设计都是耍流氓,不同场景下,状态同步,究竟是推送还是拉取呢?

用户的在线状态,分为客户端状态(端),服务端状态(云)两种形态。 什么是服务端状态?服务端状态,主要分为在线online和离线offline,不同的状态,对于不同的业务处理流程可能不同。例如对于消息的处理:(1)服务端状态在线,直接投递给用户;(2)服务端状态离线,直接存储离线消息,等用户下一次登录拉取; 如何实时更新服务端状态?用户uid-A登录时,会修改用户的服务端状态为在线。

用户uid-A登出时,会修改用户的服务端状态为离线。

经常的,服务端会将用户的服务端状态存储在高可用的缓存集群里。
 什么是客户端状态?不同的产品,会有不同的客户端状态,例如隐身、离线、忙碌、勿扰等,这些状态大多是产品功能需求。画外音:微信,在设计之初,就摒弃了用户端状态这个概念。
后文为了方便描述,不妨设待讨论的是QQ这种拥有客户端状态的产品,并假设客户端状态也只有在线和离线两种状态,后文统一称为“用户状态”。 如何获取好友的状态?uid-A登录时,先去数据库拉取自己的好友列表,再去缓存获取所有好友的状态。

用户uid-A的好友uid-B状态改变时(由登录、登出等动作触发),uid-A如何同步这一事件?这里就有推拉的设计折衷了。
情况一:如果对于状态变更实时性要求不高,可以采用拉取。uid-A向服务器轮询拉取uid-B(其实是自己的全部好友)的状态,例如每1分钟一次,其缺点是:(1)如果uid-B的状态改变,uid-A获取不实时,可能有1分钟时延;(2)如果uid-B的状态不改变,uid-A会有大量无效的轮询请求,非常低效; 情况二:如果对于状态变更实时性要求较高,则必须推送。uid-B状态改变时(由登录、登出等动作触发),服务端不仅要在缓存中修改uid-B的状态,还要将这个状体改变的通知推送给uid-B的在线好友。

推送的优势是:实时。

缺点是:当在线好友量很大时,任何一个用户状态的改变,会扩散成N个实时通知,这个N叫做“消息风暴扩散系数”。假设一个IM系统平均每个用户有200个好友,平均有20%的好友在线,那么消息风暴扩散系数N=40,这意味着,任何一个状态的变化会变成40个推送请求。 群友状态的一致性,和好友状态的一致性相比,复杂在哪里?可不可以采用实时推送?群这个业务场景大伙也非常之熟悉,你能够加入若干群(例如20个),假设平均每个群有200人,即你会有4000个群友。 理论上群友状态也可以通过实时推送的方式实现,以保证实时性。进一步讨论之前,先一起估算下这个业务场景下的“消息风暴扩散系数”。 假设平均每个用户加了20个群,平均每个群有200个用户,依然假设20%的用户在线,那么为了保证群友状态的实时性,每个用户登录,就要将自己的状态改变通知发送给20*200*20%=800个群友,N=800,意味着,任何一个状态的变化会变成800个推送请求。如果说好友状态实时推送,消息风暴扩散系数N=40尚可以接受,那么群友状态实时推送,N=800则是灾难性的。此类业务往往采用轮询拉取的方式,获得群友的状态。 轮询拉取群友状态也会给服务器带来过大的压力,还有什么优化方式?群友的数据量太大,虽然每个用户平均加入了20个群,但实际上并不会每次登录都进入每一个群。不采用轮询拉取,而采用按需拉取,延时拉取的方式,在真正进入一个群时才实时拉取群友的在线状态,是既能满足用户需求(用户感觉是状态是实时、一致的,但其实是进入群才拉取的),又能降低服务器压力。这是一种常见方法。 总结状态的实时性与一致性是一个较难解决的技术问题,不同的业务实现方式不同,一般来说:(1)好友状态同步,是采用推送的方式同步;(2)群友状态同步,由于消息风暴扩散系数过大,一般采用拉取的方式同步;(3)群友状态同步,还能采用按需拉取的优化方式,进一步降低服务端压力;(4)“消息风暴扩散系数”是指一个消息发出时,变成N个消息的扩散系数,这个系数一定程度上决定了技术采用推送还是拉取;画外音:群消息的推送,也存在“消息风暴扩散系数”的问题。

QQ好友状态,QQ群友状态,究竟是推还是拉? 网页端收消息,究竟是推还是拉?的更多相关文章

  1. 如何实现Jenkins 编译结果通知到QQ好友及QQ群组<很遗憾 2019年1月1日腾讯停止了webqq机器人的服务支持>

    Jenkins-NotifyQQ NotifyQQ 运行于Docker 本文介绍mac 环境下实现Jenkins编译结果QQ即时通知 Jenkins 安装使用及iOS自动化打包,邮件通知请参考本人博客 ...

  2. 微信sdk分享,苹果手机分享到qq好友和qq空间没有反应

    最近线上程序苹果手机进行微信分享时,分享到qq好友和qq空间,无法调用分享程序,从微信跳转到qq后就没有反应了,但是安卓手机分享就没事? 解决:调用微信sdk分享时,分享的url(link)的参数不能 ...

  3. javascript社交平台分享-新浪微博、QQ微博、QQ好友、QQ空间、人人网

    整理的五个社交平台的分享 <!doctype html> <html lang="en"> <head> <meta charset=&q ...

  4. web分享QQ好友、QQ空间、新浪微博的api接口

    QZone: "http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url={{URL}}&title={{TITL ...

  5. 微信jssdk安卓机分享QQ好友和QQ空间出现{"errMsg":"shareQQ:fail"}

    使用ajax请求appid之类的配置,然后进行wx.config和wx.ready,苹果机上是完全OK的,但是安卓机上十次有九次是失败,只有一次能成功,百度了一下,有人说是参数有空格,有人说是微信bu ...

  6. QQ群友在线/离线,如何测试?

    上篇文章『QQ好友在线/离线,如何测试?』针对即时通讯的"状态"进行了分析和总结,主要说到了QQ好友在线/离线实现方案,测试过程中需要注意的测试点. 针对好友状态实时性的要求需要使 ...

  7. QQ好友在线/离线,怎么测试?

    即时通讯是目前internet上最为流行的通讯方式,各种各样的即时通讯软件也层出不穷,那么今天主要针对QQ好友在线状态/QQ群友在线状态功能出发,一起思考其中的实现原理以及我们如何去测试此功能? 当大 ...

  8. 网站pc端分享QQ好友,空间,微博

    在开发pc端网站的过程中,涉及到邀请好友的功能,之前单纯的复制粘贴已经无法满足用户的体验.故,仿照移动端添加自动分享到QQ好友,QQ空间,QQ微博的功能. 分享到QQ好友:http://connect ...

  9. 每日技术总结:jquery datetimepicker,微博QQ好友QQ空间微信等分享接口

    前言: 1.jquery datetimepicker 今天遇到一个日期控件格式的问题,默认选中显示的并不是设定的值,而是当天的日期.于是去查了一遍文档. 参考文章:jquery datetimepi ...

随机推荐

  1. 【mybatis-plus】CRUD必备良药,mybatis的好搭档

    做开发,免不了对数据进行增删改查,那么mybatis-plus我觉得很适合我这个java新手,简单好用. 官网在这 一.什么是mybatis-plus MyBatis-Plus(简称 MP),是一个M ...

  2. JavaSwing 船只停靠管理可视化(一)

    最近抽空闲时间做了船只停靠管理系统,先看一下效果. 停靠泊位管理:实现泊位的 增删改查. JavaSwing 船只停靠管理可视化(一) JavaSwing 船只停靠管理可视化(二) JavaSwing ...

  3. 1.第一个QT程序

    第一个QT程序 应用程序类QApplication 窗口类MyWidget 进入事件循环 a.exec() 头文件 mywidget.h QApplication 文件Demo_pro 我怎么知道我用 ...

  4. 基于websocket的netty demo

    前面2文 基于http的netty demo 基于socket的netty demo 讲了netty在http和socket的使用,下面讲讲netty如何使用websocket websocket是h ...

  5. VS2017+qt5.9的安装

    VS2017+qt5.9的安装 运行环境: win7旗舰版+vs2017专业版+qt5.9.2 第一步:安装qt5.9.2 下载qt安装包:下载地址http://mirrors.ustc.edu.cn ...

  6. 第二章 信号量及条件变量(三)——> 重点

    2.4.4 信号量的应用 1. 利用信号量实现进程互斥   为使多个进程能互斥的访问某临界资源,只需为该资源设置一个互斥信号量mutex,并设置其初值为 1 ,然后讲个进程访问该资源的临界区CS置于w ...

  7. SQL Server解惑——为什么ORDER BY改变了变量的字符串拼接结果

      在SQL Server中可能有这样的拼接字符串需求,需要将查询出来的一列拼接成字符串,如下案例所示,我们需要将AddressID <=10的AddressLine1拼接起来,分隔符为|.如下 ...

  8. 震惊!java中日期格式化的大坑!

    前言 我们都知道在java中进行日期格式化使用simpledateformat.通过格式 yyyy-MM-dd 等来进行格式化,但是你知道其中微小的坑吗? yyyy 和 YYYY 示例代码 @Test ...

  9. [ABP教程]第七章 作者:数据库集成

    Web开发教程7 作者:数据库集成 关于此教程 在这个教程系列中,你将要构建一个基于ABP框架的应用程序 Acme.BookStore.这个应用程序被用于甘丽图书页面机器作者.它将用以下开发技术: E ...

  10. 利用PHP递归 获取所有的上级栏目

    /** * 获取所有的上级栏目 * @param $category_id * @param array $array * @return array * @author 宁佳兵 <meilij ...