当前位置: 首页 > news >正文

【融云分析】聊天室海量消息分发之消息丢弃策略

1 背景

随着直播、聊天室等 APP 的广泛普及应用,聊天室功能越来越被重视。比如今年非常火、下载量飙升的『直播带货』类 APP,在其直播中的用户聊天、弹幕、礼物、点赞、禁言、系统通知等场景都基于聊天室实现;如果将聊天室中产生的海量消息全量分发至客户端,那么客户端可能会出现卡顿,且此类刷屏消息人眼无法查看也会影响用户体验,因此聊天室消息分发的丢弃策略应运而生。

2 海量消息分发的挑战

我们以一个百万人观看的直播聊天室模型进行举例:

1、在直播中会有一波一波的消息高峰,比如直播中的“刷屏”消息,即大量用户在同一时段发送的海量消息,一般情况下此类“刷屏”消息的消息内容基本相同。如果将所有消息全部展示在客户端,则客户端很可能出现卡顿、消息延迟等问题,严重影响用户体验。

2、海量消息的情况下,如果服务端每条消息都长期存储将导致服务缓存使用量激增,使得内存、存储成为性能瓶颈。

3、在另外一些场景下,比如聊天室的房间管理员进行操作后的通知消息或者系统通知,一般情况下这类消息是较为重要的,需要优先保障它的到达率。

基于这些挑战,我们的服务需要做一个基于业务场景的优化来应对。

3 聊天室架构模型

融云聊天室服务经过多年迭代更新,目前已非常稳定。以下简要介绍融云的聊天室架构,架构示意图如下:
在这里插入图片描述

图3-1
简要说明:

聊天室服务-缓存聊天室的基本信息,包括用户列表,禁言封禁关系,白名单用户等

消息服务-缓存本节点需要处理的用户关系信息、消息队列信息等

  • 聊天室用户关系同步:

成员主动加入退出时:聊天室服务同步至==> 消息服务

分发消息发现用户已离线时:消息服务同步至==> 聊天室服务

*发送消息:

聊天室服务经过必要校验通过后将消息广播至消息服务

聊天室服务不缓存消息内容

Zk-各服务实例均注册到 Zk,数据用于服务间流转时的落点计算

聊天室服务:按照聊天室 ID 落点

消息服务:按照用户 ID 落点

Redis-主要作为二级缓存,以及服务更新(重启)时内存数据的备份

4 聊天室消息分发解决方案

聊天室服务的消息分发、拉取方案:
在这里插入图片描述

图4-1
分发(图4-1):

用户 A 在聊天室中发送一条消息,首先由聊天室服务处理

聊天室服务将消息同步到各消息服务节点

消息服务向本节点缓存的所有成员下发通知拉取

如图『消息服务-1』将向用户 B 下发通知

另外,在分发过程中,具有通知合并机制;上述步骤 3 详细流程为:

将所有成员加入到待通知队列中(如已存在则更新通知消息时间)

下发线程,轮训获取待通知队列

向队列中用户下发通知拉取

通过次流程可保障下发线程一轮只会向同一用户发送一个通知拉取,即多个消息会合并为一个通知拉取,有效提升了服务端性能且降低了客户端与服务端的网络消耗。
在这里插入图片描述

图4-2
拉取(图4-2):

用户 B 收到通知后将向服务端发送拉取消息请求

该请求将由『消息服务-1』节点处理

『消息服务-1』将根据客户端传递的最后一条消息时间戳,从消息队列中返回消息列表,参考图 4-3 示意

用户 B 获取到新的消息
在这里插入图片描述

图4-3
5 聊天室消息分发之消息丢弃策略
在这里插入图片描述

图5-1
5.1上行限速控制(丢弃)策略:

针对上行的限速控制,默认 200 条/秒,根据业务需要可调整。达到限速后发送的消息将在聊天室服务丢弃,不再向各消息服务节点同步。

5.2下行限速控制(丢弃)策略:

针对下行的限速控制,即对消息环形队列(图 4.3 所描述拉取消息过程)长度的控制,达到最大值后最“老”的消息将被淘汰丢弃。

每次下发通知拉取后服务端将该用户标记为拉取中,用户实际拉取消息后移除该标记。拉取中标记作用:例如产生新消息时用户具有拉取中标记,如果距设置标记时间在 2 秒内则不会下发通知(降低客户端压力,丢弃通知未丢弃消息),超过 2 秒则继续下发通知(连续多次通知未拉取则触发用户踢出策略,不在此赘述)。因此消息是否被丢弃取决于客户端拉取速度(受客户端性能、网络影响),客户端及时拉取消息则没有被丢弃的消息。

通过以上两个策略保障了客户端不会因为海量消息出现卡顿、延迟等问题;避免出现消息刷屏,肉眼无法查看的情况;同时降低了服务端存储压力,不会因为海量消息出现内存瓶颈从而影响服务。

5.3 重要消息防丢弃策略:

如前文所述,在聊天室场景下对某些消息应具有较高优先级,不应丢弃;例如聊天室的房间管理员进行操作后的通知消息或者系统通知,针对此场景,我们设置了消息白名单、消息优先级的概念,保障不丢弃。如图 5-1 所示,消息环形队列可以为多个,与普通聊天室消息分开则保障了重要消息不丢弃。

6 结束语

随着移动互联网的发展,聊天室的业务模型和压力也在不停地扩展变化,后续可能还会遇到更多的挑战,我们的服务会与时俱进、跟进更优的方案策略进行应对。

最新活动推荐:
在这里插入图片描述

相关文章:

  • 还记得你第一次视频聊天是什么时候吗?
  • 【融云分析】WebRTC 首帧显示优化策略全解析
  • 融云主办 WICC 2020 探寻互联网通信云技术风向标
  • 【融云分析】iOS 基于实时音视频 SDK 实现屏幕共享功能
  • 【融云分析】基于 ffmpeg 实现重采样和混音
  • 如“乐高”一般的通信中台到底什么样?
  • 高效灵活保障业务安全的音视频审核什么样?
  • 融云携手普元信息为国家部级单位打造协同办公平台
  • RTC vs RTMP,适合的才是最好的!
  • Flutter Platform Channel深度解析
  • 融云 SDK 5.0.0 功能迭代
  • IM 消息数据存储结构设计
  • 超大规模会议技术优化策略 轻松实现 500 人线上流畅沟通
  • 如何解决移动直播下的耳返延迟问题
  • 飞信十年珍贵历练,做 To B 别有取巧的心思
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • C++类的相互关联
  • docker python 配置
  • extjs4学习之配置
  • HomeBrew常规使用教程
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • Joomla 2.x, 3.x useful code cheatsheet
  • Theano - 导数
  • Vue.js 移动端适配之 vw 解决方案
  • 反思总结然后整装待发
  • 你真的知道 == 和 equals 的区别吗?
  • 强力优化Rancher k8s中国区的使用体验
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 试着探索高并发下的系统架构面貌
  • 通过几道题目学习二叉搜索树
  • ​​​​​​​​​​​​​​Γ函数
  • #图像处理
  • (06)Hive——正则表达式
  • (solr系列:一)使用tomcat部署solr服务
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • *2 echo、printf、mkdir命令的应用
  • .“空心村”成因分析及解决对策122344
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .Net Remoting常用部署结构
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 命令行参数包含应用程序路径吗?
  • .NET的微型Web框架 Nancy
  • .NET下的多线程编程—1-线程机制概述
  • .NET运行机制
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • [20170705]diff比较执行结果的内容.txt
  • [ANT] 项目中应用ANT
  • [BUUCTF 2018]Online Tool(特详解)
  • [Design Pattern] 工厂方法模式
  • [Django ]Django 的数据库操作
  • [JS]变量
  • [luoguP1666] 前缀单词(DP)