基于大规模边缘计算的千万级聊天室技术实践

2024-03-05 18:10

本文主要是介绍基于大规模边缘计算的千万级聊天室技术实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当前直播成为一种流行趋势,带货直播,网红带货,明星在线演唱会等,进一步使得直播聊天室变成了一个当前必备的能力,面向大型,超大型的直播场景,技术上也在不断的进行迭代更新。

大规模边缘聊天室如何工作?

大型边缘聊天室的工作过程非常的简单,用户 UserA 加入聊天室 X,用户 UserB 也加入聊天室 X,此时用户 UserA 向聊天室发送消息 hello,服务端接收到该消息后,会向 UserA 发送一个接收成功的回应,服务端同时会将消息进行扩散到所有在同一个聊天室中的人,此示例中为 UserB。

场景简单化但制作不简单

每个环节都需要额外关注

1.如何稳定,高效的保持住百万甚至千万的长连接

2.如何进行聊天室成员状态的维护

3.如何进行消息路由的选择

如何稳定超大规模的连接?

主要通过两个方向来解决这个问题,单机的连接数和集群的规模。

1.单机负载

关于单机连接的提升上,单机的连接数支撑虽然可以达到很高的数值,但是也要考虑是否为有效连接,因为高负载的连接和低负载的连接是完全不同的概念,且不说其他的业务逻辑,单纯其中的心跳保持逻辑,就会造成 CPU 和 IO 非常大的负担,这些还是完全没有谈及业务逻辑的基础上,故而在单机负载上,一般采用的是不超过10W的单机负载。

2.集群规模

集群的水平扩展能力决定了集群的规模,下图是服务端的整体部署结构:

上图中绿色的区域为负责客户端长连接的区域,所有的 IMS(IM Server)提供的服务完全相同,而且相互之间完全没有任何的依赖关系;上图中的黄色是部署在 IDC 中,主要服务聊天室的路由管理以及消息的路由分发。IMS 可以认为是可以无限水平扩展的架构设计,所以集群的规模可以认为是无限的。集群的规模上来了,尤其是在边缘侧的负载调度又称为了一个新问题,基于公司稳定而高效的边缘调度方式,通过客户端和服务端的完美配合实现高效,用户无感的连接体验。

关键:连接承载的瞬时数量

对于长连接的场景,连接保持固然重要,连接能够承载的瞬时数量也是非常关键的指标。而这个点也同样的是单机和集群的两个不同维度的问题,集群的角度则和上面的连接保持大致相同,而针对单机的连接创建和断开,则比单纯的保持住连接要复杂一些,需要考虑到登录时的鉴权问题,聊天室的特定场景,还需要考虑退出时的聊天室清理工作。

简单介绍一下整体的策略,主要将创建和断开时发生的事情分成了两大类,一类是需要同步去执行的动作,另外一类是可以进行异步处理的,则放入到异步队列进行处理。策略本身比较简单,但是真正在执行的过程中能够做到,而且能够随着版本的迭代一直保持策略则显的比较困难,为了达到该目标,我们坚持着一个原则,凡是要添加到同步逻辑中的内容,需要给明相应的理由,并且需要团队内部同步讨论,否则只能采用异步队列的方式,这里并不是说异步队列的事情不需要审核或者讨论,而且同步的需要明确的针对性的处理,这样才能保证同步逻辑的清晰以及策略的可持续性。

如何进行成员状态的维护?

聊天室属于多人聊天的一种特定的形态,消息仅仅扩散到在线的用户,用户离线则自动退出聊天室,并且再次上线后也不会接收到离线时的消息。至于像是一些断网了重新连接后还能继续观看直播的场景,进去时能够看到一些历史消息的情况,则是通过其他的手段实现自动订阅,拉取历史的能力。

成员的分级管理 

上图中的左侧为聊天室与用户直接对应的关系表,也就是图中的用户聊天室信息,同步会产生聊天室成员信息,后续在消息路由的情况下,会高频的使用该结构查询聊天室的人员,进一步进行消息的扩散。分层的核心点在于节点聊天室的维护,只在当前节点的聊天室列表发生变化时才会修改节点聊天室信息,并且将该变更同步到 IDC,也即是上一次路由表中。这里只有第一个人加入聊天室和最后一个人退出聊天室时才会触发相应的逻辑。

上面是进一步抽离了关于分级注册的逻辑,由每一级将当前层级的聊天室对应关系注册,保活到上一级的聊天室关系中,我们也仅仅验证了3层,至于更多的层级理论上是可行的,但是不推荐使用,每增加一层复杂度和对异常情况的处理就会翻倍,对于后续介绍的消息投递则必须是所有的层级都正常工作才能将消息正常投递下来。

成员的心跳保持

本节点上的聊天室信息由于都是内存级别的操作,所以一般出问题的概率比较小。保障其一致性比较简单,但是跨节点,尤其是跨机房的,跨地区的网络交互,很难保证每次都是正常的,所以在同步相关的信息的时候,添加了类似的保活机制,异步队列机制,重试机制等来进一步保障业务的稳定性,当然还有及时异常处理机制,毕竟不能让用户进入了聊天室,但是确一直不能接收消息,还不能恢复当前的状态。

如何进行消息路由的选择?

多级路由

基于上面的分级注册的逻辑,可以看出消息的下发也是分级进行下发的,这种设计上减少了每层的下发的难度,举个例子如果有200IMS,10个Edge,则极端情况下IDC需要分发的数量为10个,每个Edge的分发数量为20个,如果只有一级的话,则IDC需要分发200个请求,这个看着不是一个很大的数字,但是不要忘记这个仅仅为一条消息的分发量,而如果有5000请求则是200*5000=1,000,000则有百万级别的分发量,通过分级的方式能够有效的降低各个层级的复杂度,同时也能尽量减少跨机房,跨地区的调用,进一步降低风险。分级分发虽然带来了好处,也使得路径的维护变得相对复杂很多。

消息推拉结合

聊天室的场景,大部分场景下是采用直接推送消息的方式。大型的聊天室消息的过滤,筛选以及丢弃的策略的方式也是非常复杂的问题。至于消息到投递阶段之后,直接推消息给客户端,这样消息的即时性确实得到了保证,但是客户端的情况是不同的,机器的配置不同,机器当时的运行状态不同,网络状况也是不同的,所以在这种情况,需要支持客户端能够根据自己的情况进行拉取一定数量的消息,这样能够更加灵活的适应不同的场景。这些策略虽然说这简单,但是真正的落实到线上的服务,还是有很多的细节点需要考虑,真正做到稳定还是比较困难的,毕竟这种特定的场景期望很好的监控也是比较困难的。我们也是先从简单的固定模式的推拉方式进行处理,后续根据具体的情况进行更加细节性的调优。

固定路由

针对一些明确大型直播的场景需求,也提供了一种简单的路由方式,从上述的聊天室路由管理,可以看出出问题的情况还是可能存在的,所以针对已知特别大的聊天室场景,该场景的话,可以认为能够覆盖到所有的 IMS 服务,所以聊天室的分级注册就显得有点多余,所以聊天室级别的注册变更为节点的注册,依赖系统的服务注册发现默认就完成相关的内容,这样整个事情就变得非常的简单高效了。

这种方式有其在这种超大型聊天室的优势,也存在其自身的瓶颈点,所以的消息不管是否在本节点有用户加入了该聊天室,消息都会投递到该节点,故而每个 IMS 都要处理所有的消息,尽管很多的消息是没有下发投递的需求。方案没有万能的,所以这两种处理方式是互补的,并不是互斥的。

大规模边缘聊天室 VS 中心集群

大规模边缘聊天室的方案,相较于传统的中心集群式的聊天室,从技术的大的架构是没有本质的区别,依然是多级路由,消息推拉结合的方式。

不同的点在于部署的形态不同,而恰恰是这些的不同使得很多东西发生了变化。大规模边缘聊天室的方式,增加了边缘的连通性,能够在更加靠近用户的地方进行就近部署,达到解决最后五公里的目的。并且能够利用各个机房的资源,从而达到百万,千万级别甚至更高量级的用户数量。大规模边缘聊天室的方案在实施的过程中,对成本的降低也起到了关键作用,由于中心机房一般保证可用性和稳定性,一般采用的都是 BGP 的网络,成本相对边缘机房的非 BGP 网络要贵很多。系统整体可用性的角度,大规模边缘聊天室相比于中心集群式的聊天室,对于机房故障的容灾性更好。当然这里主要介绍了大规模聊天室的优点,任何一种方案都不是全能的,有其优点就有其自身的劣势。大规模边缘聊天室部署形态复杂,对于运维体系的要求相对较高,服务间网络稳定性也比较难以保障,所以一般适用于对大规模的,公开的聊天室,对于比价多精细玩法的场景,或者小规模不太适合,反而增加了很多的不确定性。

大规模边缘聊天室 VS CDN方式

针对大规模聊天室,曾考虑过是否可以使用业界比较成熟的 CDN 分发技术。在具体的实践过程中发现,针对这种小包,而且不会重复分发的场景,这里指的是同一个消息,不太会被一段时间不断的获取,聊天室的场景一般是当时收到了就收到了,如果没有收到,后续也不太期望需要收到消息。而且 CDN 的方案都是将消息聚合后,客户端定时拉取的方式,消息存在重叠性,延时性等不能满足客户的需求。

技术难度上,加入1000万的聊天室,每10s重新刷新一次消息,也有将近100W的 QPS 请求,这对于 CDN 系统也是一个非常大的调整,而且即使接入多家的 CDN 也会存在比较高比例的超时。更何况10S的延时,对于有些场景已经能够明显感知到了。

大规模聊天室相对于集中式,单中心的方案,不仅仅在服务的稳定性,承载的用户量级上有了显著的提升,而且在成本上也能有大幅的降低,同时用户体验也变得更好。至于业界一直尝试的 CDN 的聊天室方案同样存在着本身的局限性,不同于音视频消息单个内容相对较小,瞬时性访问量较大,重复访问的概率几乎没有等特定,使得 CDN 的实践方案无法满足该场景的需求。如2022卡塔尔世界杯期间,环信针对运营商客户对于世界杯的直播聊天室进行专业改造,并且帮助客户实现千万级聊天室的技术支持。解决了客户对于世界杯赛事直播海量用户在线的需求,通过架构的调整,能够同时支撑1800万用户同时在线,消息的处理能力达到了5000 QPS,消息的下发量达到了4000万+/秒的级别。环信整体方案不仅能够支持到如此大规模的量级,而且成本也能够比肩 CDN 的方案,机器能够进行高效的扩缩容。

相关文档:

注册环信:环信即时通讯云

集成文档:产品概述 | 环信 IM 文档

imgeek社区支持:环信开发者社区-为移动开发者提供IM服务 - IM Geek开发者社区-移动开发者社区-开源社区-IM Geek官网

这篇关于基于大规模边缘计算的千万级聊天室技术实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/777377

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

Python实现PDF按页分割的技术指南

《Python实现PDF按页分割的技术指南》PDF文件处理是日常工作中的常见需求,特别是当我们需要将大型PDF文档拆分为多个部分时,下面我们就来看看如何使用Python创建一个灵活的PDF分割工具吧... 目录需求分析技术方案工具选择安装依赖完整代码实现使用说明基本用法示例命令输出示例技术亮点实际应用场景扩

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Olingo分析和实践之ODataImpl详细分析(重要方法详解)

《Olingo分析和实践之ODataImpl详细分析(重要方法详解)》ODataImpl.java是ApacheOlingoOData框架的核心工厂类,负责创建序列化器、反序列化器和处理器等组件,... 目录概述主要职责类结构与继承关系核心功能分析1. 序列化器管理2. 反序列化器管理3. 处理器管理重要方