好友列表和群聊列表的用户状态应该“推”还是“拉”

推送方式

优点:

  1. 实时

缺点:

  1. 当用户量很大时,任何一个用户状态改变,会扩散N个实时通知,这个N叫做“消息风暴扩散系数”,会有大量的实时推送请求
  2. 会造成大量离线垃圾消息的推送

拉取方式

缺点:

  1. 状态变化不实时,会存在延迟的情况
  2. 如果用户状态未发生变化,会有大量的无效轮询请求,占用服务器资源

好友列表状态该采取哪种方式?

  1. 用户登录的时候,可以通过拉取方式获取全部好友的状态
  2. 用户登录过后,如果实时性要求较高,可以采用推送方式同步;如果不高可以采用拉取方式

群聊列表状态为什么不使用推送?

  1. 正如推送的缺点,因为群友的状态的“消息风暴扩散系数”太大了,全部实时获取系统往往承受不了。假设平均每个用户加了20个群,平均每个群有200个用户,依然假设20%的用户在线,那么为了保证群友状态的实时性,每个用户登录,就要将自己的状态改变通知发送给20 * 200 * 20%=800个群友,N=800,意味着,任何一个状态的变化会变成800个推送请求。

轮询拉取也会给服务器带来巨大压力,应该怎么优化?

  1. 按需拉取。群友的数据量太大,虽然每个用户平均加入了20个群,但实际上并不会每次登录都进入每一个群。不采用轮询拉取,而采用按需拉取,延时拉取的方式,在真正进入一个群时才实时拉取群友的在线状态,是既能满足用户需求(用户感觉是状态是实时、一致的,但其实是进入群才拉取的),又能降低服务器压力。这是一种常见方法。
  2. 每次拉取更少的数据。比如只是为了更新用户的状态,就没必要将用户的最新详细也拉取下来,如头像、动态、签名等这些数据尽量使用延迟拉取
  3. 时间戳。不确定本地数据是否最新,拉取服务器时间戳与本地时间戳进行比对,如果本地是最新的数据,就能避免重新拉取。id列表数据的变化频度是比较低的(增加id,减少id),时间戳机制非常的有效。(这里涉及到本地时间戳与服务器时间同步的问题,这个后面会介绍)

你可能感兴趣的:(好友列表和群聊列表的用户状态应该“推”还是“拉”)