高可用消息服务消息一致、可靠性、链路稳定性核心关注点

news2024/11/25 15:50:23

面临的问题

初期业务主要的场景是直播间的群聊消息以及一小部分的单聊消息。由于是教育场景,所以业务在划分聊天室的时候是以班级为单位进行划分的,假设每个聊天室的人数为500人。

问题一:用户的维护

直播场景的群聊与微信等常见的群聊在用户维护上有很大区别。微信的群用户关系相对比较固定,用户进群退群是相对低频操作,用户集合相对固定。而直播间里的用户进出是非常频繁的,而且直播间是有时效性的。实际进出直播间峰值QPS不会超过1万,使用Redis可以解决聊天室用户列表存储及过期清理问题。

问题二:消息转发

当一个500人的聊天室所有用户同时发送消息时,消息的转发QPS为500*500=2.5w。从直播用户端视角考虑:

​ 实时性:如果消息服务做消峰处理,峰值消息的堆积会造成消息延时增大,而有些信令消息具有时效性,太大延迟会影响用户的体验及互动实时性。

​ 用户体验:端展示各类用户聊天和信令消息一般一屏不会超过10-20条; 如果每秒超过20条消息下发会出现持续刷屏的现象; 大量的消息也会给端上带来持续的高负荷。

因此我们为消息定义了不同的优先级。高优先级消息优先转发处理并且保证不丢弃; 低优先级消息进行一定丢弃策略后再进行转发。

问题三:历史消息

业务上需要生成回放视频,需要获取历史信令、互动聊天等消息。要求能够快速写入历史消息以保证消息转发的时效性。

消息的保存主要包含写扩散和读扩散两大类。我们采用读扩散的方式,读扩散可以减少存储空间,也可以减少消息保存的时间。考虑到回放的优先级不高,所以在存储组件的选择上我们选择了PikaPika是接口与Redis类似可以减少学习、开发成本。同时由于它是采用追加的方式,所以写性能可以与Redis媲美。

问题四:消息顺序

信令消息顺序的要求,需要保证同一个人发送消息的顺序,以及需要保证同一个聊天室内的用户收到消息顺序都是相同的。

解决消息顺序可以使用Kafka之类的队列来保证,但是用Kafka有一定的延迟。为了降低延迟我们采用一致性哈希的策略来处理消息的转发,稍后会详细介绍。

设计目标

打造稳定、高效的消息通讯服务端。

  • 提供高可靠、高稳定、高性能的长连接服务;
  • 支撑百万长连接同时在线;
  • 支持多集群快速部暑,扩容;

稳定性和扩展性

稳定性和扩展性在整体架构是非常重要的部分,消息服务主要的策略是动态配置策略下发,可以有效的实现多机房的动态调度,故障的自动转移,同时也具备了横向扩展的能力。

  • 配置:每个端在连接服务端之前,会获取SDK的常用配置信息,比如重试策略、超时时间等核心参数和业务的调度地址
  • 调度:根据不同的业务类型和用户信息,请求调度地址获取到当前服务的连接地址
  • 连接:向目标服务集群发起连接
  • 故障转移:如果服务中途发生问题导致断线,会再次发起调度,后端集群会重新计算可用的集群,将用户调度到可用集群节点
  • 断线的可能有多种多样,常见的有以下方面:
    • 网络不稳定,导致网络丢包,触发心跳超时
    • 客户端,服务端发生异常,主动关闭连接
  • 在配置和调度接口高可用的层面,会采用多地址轮询,多次重试, CDN 静态资源兜底等策略来依次保障

大家应该会疑问,为什么不把调度地址在第一步的配置服务中一起返回,要拆分为两步进行?这里其实是考虑消息服务支持多业务的并发,配置服务在初始化SDK的时候只获取一次,获取 SDK 的核心控制参数。后续不同的业务可以在不同时机动态获取各自的调度地址,可以有效的提升业务的隔离性和稳定性,做到业务之间互不影响。

安全性

在安全性和抗攻击性方面采取了一系列的措施,对消息内容的加密和账户的安全认证,我们目前采用的方式有:

  • 为每个 App 业务方下发 AppKey,在调度过程中会校验签名,以免不安全的流量拿到调度地址,或者至少需要突破 App 的防御才能拿到
  • 调度拿到的接入地址中会有合法的 Token,服务端 Auth 模块会验证 Token 的时效性以及合法性,以及用户的账户体系,以免不法分子投机,增加破解成本
  • 可动态开启内容加密功能,会获取用户独立的对称加密AES密匙,进行内容加密传输
  • 数据传输使用 TLS / SSL 隧道加密
  • 利用安全的网络环境,比如 IDC 的机房防护,云厂商的智能防护等

连接的稳定性

在真实复杂的网络环境中,可能有极少部分用户网络稳定性方面比较差,存在丢包,导致频繁断线,或者彻底无法建立连接。我们一方面会收集客户端的网络状态日志,对用户进行诊断;另一方面还针对这最后一公里的问题进行网络加速。

   使用云厂商的 TCP 加速,Websocket 加速,解决部分边缘用户的连接问题

   自建边缘节点,可以更加精细化的控制

   海外网络加速,对接多家云服务厂商

可靠性和一致性

作为消息服务的核心保障,分别会在服务端和客户端的架构中重点介绍,主要保障策略为:

  • 消息的严格确认机制,保证客户端发送到服务端的消息,只要确认后,就一定会落盘,从而保障上行消息不丢,之后下行消息可以多次重试
  • 客户端失败重传,排序,超时等策略,主要借鉴 TCP 滑动窗口的思想,可以将已确认顺序的消息返回业务层,乱序的消息要根据策略超时等待
  • 服务端的防止重复提交和重发策略
  • 全局唯一的消息 ID 和局部有序的序列号,来保障唯一性和顺序性

服务端消息ID的设计

消息 ID 的设计对消息的可靠一致性有着非常重要的意义,一方面要保证任何一条消息可追溯查询,保证消息的唯一性;另一方面需要保证消息的顺序性。

全局消息唯一ID 

消息服务生成唯一 ID 的算法借鉴 Twitter 雪花算法 Snowflake,做了一些切合服务的微调。

局部有序的序列ID

在有序序列 ID 上,我们采用一些创新的设计,为每个会话,例如一组单聊,一组群聊都会生成独立的序列号。互相没有影响,可以大幅提升序号的发号性能。序号的主要的目的是为了保障消息的局部顺序性。那么服务端在实现可靠性和一致性上做了哪些工作呢?首先我们对消息结构做了重新设计,新的消息结构如下图:

新的消息结构是类似于单向链表,与传统的单向链表的区别在于链表是逆序的,每条消息都有一个前序消息的 SeqId、本条消息的 SeqId、全局消息 Id (消息追踪使用)。消息的 SeqId 都是针对于聊天对象的,例如聊天室 A 和聊天室 B 的消息 SeqId是相互独立的。

这里采用一个前序 ID 的主要考虑是可以利用单调递增的序列来保障消息的可靠一致性,注意这里并没有要求连续单调递增。比如图中我们的序列号为:101102104107。我们可以采用一些支持海量高性能的序列号生成服务来支持,采用预先分配号码段的策略来提升性能。有兴趣的话大家可以网上查询一些比较成熟的方案。当然,消息体量不大的基础上可以简单粗暴的使用 Redis 生成连续递增的序号。

消息可靠性一致性保障

消息的可靠性一致性主要体现在以下几个方面:

  • 端上收到的消息不丢,不重,不乱序
    有了前面介绍的 SeqId,客户端就可以对消息进行排序、空洞判断等逻辑处理,具体流程如下图:

  • 同一房间内用户看到的消息顺序一致
  • 用户发送的顺序和用户接收到的顺序一致

后面两个特性,服务端主要是通过将同一发送者的消息 Hash 到同一线程中进行处理,同一个房间内的消息,也 Hash 到同一个线程内处理。

  • 发送重传

        客户端如果消息发送失败了怎么保证消息可靠呢?

        为了保证发送重传并且消息不重复我们做了两件事:

  1. 首先同样我们也引入一个序列号,这个序列号是用户级别的,一个用户在线期间只会维护一个序列号,这个序列号是单调递增的。当客户端发送失败时会尝试一定次数的重发,如果 N 次都重发失败会回调通知业务层。客户端重发的时候序列号是保持不变的,因为序列号是单调递增的,所以服务端就可以通过判断序列是否重复来区别是否是重发的消息。

  2. 其次服务端会缓存一定时间的消息发送结果,当判断消息为重传时会查询上一次发送结果,直接把结果返回给客户端。整体流程如下图:

  • 现场恢复

用户遍布全国各地,每个用户的网络情况都不一样,而且质量千差万别,所以对于 TCP 长连接掉线的情况是再正常不过。因为在掉线到重新连接上这段时间内服务端是无法正常将消息转发该用户的,我们通过下图所示的流程来保障用户重连后能收到丢失的消息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/456593.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

可视化大屏模板|不玩虚的,套用立得报表

写在前面:这是报表,是可视化大屏报表,是可以直接套用来分析我们自己数据源的可视化大屏报表模板。不是单纯的图片! 在一些社交平台上经常看到有人误将可视化大屏图片当做报表求分享。可以理解大家都想要将报表做得好看&#xff0…

信息收集(三)端口和目录信息收集

信息收集(一)域名信息收集 信息收集(二)IP信息收集 端口是什么 "端口"是英文port的意译,可以认为是设备与外界通讯交流的出口。端口可分为虚拟端口和物理端口,其中虚拟端口指计算机内部或交换机…

Matlab绘图中的一些技能

目录 1、matlab坐标轴设置多种字体(复合字体) 2、matlab图片中title生成的标题转移至图像下端 3、指定对应格式和期望dpi的图像进行保存、以及不留白保存 4、设置字体字号(x、y轴,标题。全局字体等) 5、设置刻度值信息,只有左…

ConcurrentHashMap是如何保证线程安全的

ConcurrentHashMap是如何保证线程安全的 定义和问题解决JDK 1.7实现原理JDK 1.8性能优化总结 定义和问题解决 ConcurrentHashMap相当于HashMap的多线程版本。 它的功能本质上和HashMap没有什么区别,因为HashMap在并发操作的时候会出现各种问题,比如&am…

Android混淆和反混淆

本篇来介绍下Android的混淆和反混淆,说起混淆,大家都会很自然地想到ProGuard,此外还有R8。事实上,AGP3.3之后,官方默认使用R8做代码优化、混淆和压缩。ProGuard和R8常常用于混淆最终的Android项目,增加项目…

Vue-router【VUE】

6. vue-router 6.1 相关理解 6.1.1 vue-router 的理解 路由就是一组key-value的对应关系。多个路由,需要经过路由器的管理vue是一个插件库,专门用来实现SPA应用。 6.1.2 对SPA应用的理解 单页 Web 应用(single page web application, SP…

C++基础阶段入门 (1)

1.C统一初始化: 初始化列表解决方案: //C语言的初始化方案 int main() {int a 10;int* ip nullptr;int ar[] { 12,23,34,45,56,67 }; } C 初始化:使用{ } int main(){//char ch a;char ch{ a };//int a 10;int a{ 10 };int b int(10);int x{ 10…

企业软文怎么写吸引人?教你几招

企业每年都要投放大量的商业软文到热门的内容平台上,也许现在你阅读的某篇文章,就是一篇企业软文。 真正厉害的软文在于你根本看不出来这是一条广告,从而让你心甘情愿的为某个产品掏腰包。企业软文到底怎么写才吸引人,接下来伯乐…

sfavsrv导致主机负载高

下午接客户电话,监控告警了,主机负载高,登录后top查看,确实比较的高 再次查看负载高的cpu发现是sfavsrv 吓了一跳,还以为中毒了,发给客户检查是否自行部署了第3方软件,确实第3方的,关…

如何将pdf图片文字转换成word 文字word图片怎么转换pdf

如今大家在工作中常常会运用到电脑来办公,电脑的运用大大提高了我们的工作效率,在带来机会的同时同样也带来了新挑战。 pdf图片怎么转换成word文档?PDF格式是一种常用的文档格式,它可以保持文档内容和格式的完整性,但是…

4月有8本SCIE期刊被剔除(附MDPI/Frontiers/Hindawi最新在检期刊)

2023年4月SCI、SSCI期刊目录更新 2023年4月18日,科睿唯安更新了WOS期刊目录,继上次3月WOS期刊目录剔除50本SCIE&SSCI期刊之后,此次4月更新又有8本SCIE期刊发生变动,其中有4本期刊被踢出SCIE数据库,4本期刊更改了名…

QMS-云质说质量 - 2 你真的知道什么是质量吗

云质QMS原创 转载请注明来源 作者:王洪石 引言 暴露的只是冰山一角 注:()中为ISO9000:2015 质量管理体系基础和术语的编号 一个组织的质量管理(3.3.4),可包括制定质量方针(3.5.9)和质量目标(3.7.2),以及通…

Web 攻防之业务安全:接口未授权访问/调用测试(敏感信息泄露)

Web 攻防之业务安全:接口未授权访问/调用测试 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台(操作系统、数据库,中间件等)、业务系统自身(软件或设备)、业…

火车站闸机web3d数字展示平台全方位动态呈现设备细节

智能互联网时代,传统的图片、文字、视频等产品展示方式,因为缺少互动性,很难引起用户的兴趣,已经逐渐失去了宣传优势。 Web3D交互展示技术的出现,让众多品牌和企业找到了新的方向,线上产品展示不在枯燥无趣…

少儿编程 中国电子学会图形化编程等级考试Scratch编程一级真题解析(选择题)2023年3月

2023年3月scratch编程等级考试一级真题 选择题(共25题,每题2分,共50分) 1、下列说法不正确的是 A、可以从声音库中随机导入声音 B、可以录制自己的声音上传 C、可以修改声音的大小 D、不能修改声音的速度 答案:D…

计算机网络第1章(概述)

文章目录 1.1、计算机网络在信息时代的作用1.2、因特网概述1、网络、互连网(互联网)和因特网2、因特网发展的三个阶段3、因特网的标准化工作4、因特网的组成 1.3 三种交换方式1、电路交换(Circuit Switching)2、分组交换&#xff…

Composer使用教程

Composer使用教程 前言1.Composer 简介2. 下载与安装2.1 局部安装2.2 全局安装2.3 更新composer2.4查看composer2.5 安装composer镜像加速 3. composer的使用3.1初始化3.2安装第三方包 4. 自动加载器4.1 加载非 class 文件4.2 加载自己写 class 文件4.3 PSR-4 自动加载规范 5. …

【脱产二站上岸】上海交大819复习经验总结

笔者来自通信考研小马哥23上交819全程班学员 本科西南某985,成绩排名中下(面试被老师疯狂吐槽),一战本校,初试分数差10来分被刷。21年12月考完数学和专业课出来就知道考不上了,分数一出就下决心二战&#…

软件测试,想找一份20k以上的工作需要掌握哪些知识?

都知道IT行业是高薪人员的聚集地,但想要成为高薪程序员却并不容易。月薪20k是测试工程师的一个门槛,想要突破就必须掌握更多的技能。 因为程序员职业发展很快,即使是相同起点的人,经过几年的工作或学习,会迅速拉开极…

Python列表和字典前面为什么要加星号(**)?

人生苦短,我用python 今天来和大家一起学习一下为什么Python列表和字典前面会加星号()?** python 安装包资料:点击此处跳转文末名片获取 Python 中, 单星号*和双星号**除了作为“乘”和“幂”的数值运算符外&#xff…