状态同步,究竟是推还是拉?

简介: 状态同步,有好友状态的同步,有群友状态的同步,有的需要实时同步,有的能够容忍延时。结合具体场景来看下,状态同步,究竟是推还是拉。

任何脱离业务的架构设计都是耍流氓。

状态同步,有好友状态的同步,有群友状态的同步,有的需要实时同步,有的能够容忍延时。结合具体场景来看下,状态同步,究竟是推还是拉。

用户的在线状态,分为客户端状态(端),服务端状态(云)两种形态。

什么是服务端状态?

服务端状态,主要分为在线online和离线offline,不同的状态,对于不同的业务处理流程可能不同。例如对于消息的处理:

  • 服务端状态在线,直接投递给用户
  • 服务端状态离线,直接存储离线消息,等用户下一次登录拉取

如何实时更新服务端状态?

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

image.png

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

image.png

经常的,服务端会将用户的服务端状态存储在高可用的缓存集群里。

什么是客户端状态?

不同的产品,会有不同的客户端状态,例如隐身、离线、忙碌、勿扰等,这些状态大多是产品功能需求。有的产品,例如微信,在设计之初,就摒弃了用户端状态这个概念。

后文为了方便描述,不妨设待讨论的是QQ这种拥有客户端状态的产品,并假设客户端状态也只有在线和离线两种状态,后文统一称为“用户状态”。

如何获取好友的状态?

uid-A登录时,先去数据库拉取自己的好友列表,再去缓存获取所有好友的状态。

image.png

用户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的在线好友。

image.png

推送的优势是:实时

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

群友状态的一致性,和好友状态的一致性相比,复杂在哪里?可不可以采用实时推送?

群这个业务场景大伙也非常之熟悉,你能够加入若干群(例如20个),假设平均每个群有200人,即你会有4000个群友。

理论上群友状态也可以通过实时推送的方式实现,以保证实时性。进一步讨论之前,先一起估算下这个业务场景下的“消息风暴扩散系数”。

假设平均每个用户加了20个群,平均每个群有200个用户,依然假设20%的用户在线,那么为了保证群友状态的实时性,每个用户登录,就要将自己的状态改变通知发送给2020020%=800个群友,N=800,意味着,任何一个状态的变化会变成800个推送请求。如果说好友状态实时推送,消息风暴扩散系数N=40尚可以接受,那么群友状态实时推送,N=800则是灾难性的。此类业务往往采用轮询拉取的方式,获得群友的状态。

轮询拉取群友状态也会给服务器带来过大的压力,还有什么优化方式?

群友的数据量太大,虽然每个用户平均加入了20个群,但实际上并不会每次登录都进入每一个群。不采用轮询拉取,而采用按需拉取,延时拉取的方式,在真正进入一个群时才实时拉取群友的在线状态,是既能满足用户需求(用户感觉是状态是实时、一致的,但其实是进入群才拉取的),又能降低服务器压力。这是一种常见方法。

总结

状态的实时性与一致性是一个较难解决的技术问题,不同的业务实现方式不同,一般来说:

  • 好友状态同步,是采用推送的方式同步
  • 群友状态同步,由于消息风暴扩散系数过大,一般采用拉取的方式同步
  • 群友状态同步,还能采用按需拉取的优化方式,进一步降低服务端压力
  • “消息风暴扩散系数”是指一个消息发出时,变成N个消息的扩散系数,这个系数一定程度上决定了技术采用推送还是拉取
目录
相关文章
|
存储 对象存储 UED
CDN适用哪些场景?
CDN是将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。今天为大家分享几个CDN的典型适用场景。
16745 0
|
7月前
#我用Qwen3做了英语老师玛丽# 、#阿里云百炼#,@通义大模型
通过Qwen3创建了名为“玛丽”的英语老师智能体,具备解决学生英语问题的多种功能。她能用英语描述天气、翻译古诗词、撰写英语作文,还帮助了解外国文化、饮食与风俗习惯。相比以往版本更易使用,体验更佳。已完成功能设计与发布流程,感兴趣者可尝试使用。
214 12
|
9月前
|
编解码 搜索推荐 开发者
《深度剖析:鸿蒙系统不同终端设备的UI自适应布局策略》
在万物互联时代,鸿蒙系统凭借分布式理念和技术架构,在智能终端领域迅速崛起。然而,如何实现应用在多设备上的完美UI布局成为关键挑战。本文探讨了鸿蒙UI自适应布局的重要性、技术原理及设计原则,包括灵活的布局组件(Row、Column、Flex)、尺寸单位适配(lpx)、媒体查询与断点机制,以及基于用户体验的设计方法。通过实践案例分析,展示了音乐应用在手机、平板和智能电视上的出色表现,并展望了未来智能化、个性化的布局趋势。掌握这些技术与原则,开发者将为用户带来更优质的跨设备体验,推动鸿蒙生态繁荣发展。
292 8
|
设计模式 存储 缓存
微服务架构下的数据库设计策略
本文探讨了在微服务架构中进行数据库设计时,如何平衡数据的一致性、独立性与系统整体性能之间的关系。文章首先介绍了微服务架构的基本概念及其对数据库设计的影响,随后深入分析了三种主流的数据库设计模式——集中式、去中心化和混合模式,并结合实际案例讨论了它们的适用场景与优缺点。此外,还提出了一系列最佳实践建议,旨在帮助开发者更好地应对微服务环境下的数据管理挑战。
|
自然语言处理 达摩院 搜索推荐
阿里推出文本搜索排序新技术,登顶国际权威NLP榜单MS MARCO
3月28日,阿里巴巴团队以0.450的得分,刷新了国际权威自然语言处理(NLP)榜单MS MARCO短文本检索排序任务历史纪录。据悉,搜索团队最新研发的文本检索及排序技术已通过阿里云智能开放搜索OpenSearch产品对外输出。
1451 0
阿里推出文本搜索排序新技术,登顶国际权威NLP榜单MS MARCO
|
消息中间件 Java Shell
RocketMQ概念详细之NameServer
NameServer 相关信息
5321 0
|
存储 SQL 关系型数据库
|
监控 网络协议 搜索推荐
各类商业场景下蓝牙Mesh技术的应用(三)|学习笔记
快速学习各类商业场景下蓝牙Mesh技术的应用(三)
各类商业场景下蓝牙Mesh技术的应用(三)|学习笔记
|
存储 缓存 安全
图解用户登录验证流程,写得太好了!
图解用户登录验证流程,写得太好了!
846 0
图解用户登录验证流程,写得太好了!
|
弹性计算 应用服务中间件 Linux
阿里云:快速搭建Docker环境
​ Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付,测试和部署代码,可以大大减少编写代码和在生产环境中运行代码之间的延迟。而容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。而本次实验是基于docker与容器的知识,介绍如何基于阿里云ECS快速搭建Docker环境,并使用Docker部署一个Nginx服务,制作自己的镜像并上传至DockerHub。 ​
2410 0
阿里云:快速搭建Docker环境