QQ状态同步究竟是推还是拉
最后更新于:2022-04-02 04:12:19
[TOC]
> [参考](https://www.w3cschool.cn/architectroad/architectroad-qq-status-consistency.html)
## 好友状态一致性
uid-B状态改变时(由登录、登出、隐身等动作触发),服务器不仅在缓存中修改uid-B的状态,还要将这个状体改变的通知**推送**给uid-B的在线反向好友(反向好友是指:加了uid-B为好友的人,而不是uid-B的好友,这个细节要注意)
![UTOOLS1576159382396.png](http://yanxuan.nosdn.127.net/7b09a29a1b844e9db0544d7b615d4ebb.png)
优点:
(1)实时
缺点:
(2)当在线好友量很大时,任何一个用户状态的改变,会扩散成N个实时通知,这个N叫做“**消息风暴扩散系数**”。
假设一个im系统平均每个用户有200个反向好友,平均有20%的反向好友在线,那么消息风暴扩散系数N=40,这意味着,任何一个状态的变化会变成40个推送请求。
## 群友状态一致性
理论上群友状态也可以通过实时推送的方式实现,以保证实时性。但实际上,群友状态一般都是采用拉取的方式获得,因为群友状态“消息风暴扩散系数”N实在太大,全部实时获取系统往往承受不了。
假设平均每个用户加了20个群,平均每个群有200个用户,依然假设20%的用户在线,那么为了保证群友状态的实时性,每个用户登录,就要将自己的状态改变通知发送给20*200*20%=800个群友,N=800,意味着,任何一个状态的变化会变成800个推送请求。
群友的数据量太大,虽然每个用户平均加入了20个群,但实际上并不会每次登录都进入每一个群。**不采用轮询拉取,而采用按需拉取,延时拉取**的方式,在真正进入一个群时才实时拉取群友的在线状态,是既能满足用户需求(用户感觉是状态是实时、一致的,但其实是进入群才拉取的),又能降低服务器压力。这是一种常见方法
## 总结与建议
状态的实时性与一致性是一个较难解决的技术问题,不同的业务接受度,不同的数据量并发量在线量,实现方式不同,个人建议的方式是:
(1)好友状态,如果对实时性要求较高,可以采用推送的方式同步;如果实时性要求不高,可以采用轮询拉取的方式同步
(2)群友的状态,由于消息风暴扩散系数过大,可以采用按需拉取,延时拉取的方式同步
(3)系统消息/开屏广告等对实时性要求不高的业务,可以采用拉取的方式获取消息
(4)“消息风暴扩散系数”是指一个消息发出时,变成N个消息的扩散系数,这个系数与业务及数据相关,一定程度上它的大小决定了技术采用推送还是拉取
';