自研分布式IM-HubuIM RFC草案

news2025/1/12 1:43:19

HubuIM RFC草案

消息协议设计

基本协议

评估标准

  1. 【性能】协议传输效率,尽可能降低端到端的延迟,延迟高于200ms用户侧就会有所感知

  2. 【兼容】既要向前兼容也要向后兼容

  3. 【存储】减少消息包的大小,降低空间占用率,一个字节在亿级别并发之下也是一亿个字节

  4. 【计算】减少编解码时造成的CPU使用率的权衡

  5. 【网络】尽可能减少网络带宽消耗

  6. 【安全】协议安全性

  7. 【迭代】要能够快速迭代,灵活拓展

  8. 【通用】可跨平台接入,H5,IoT设备等等

  9. 【可读】

基本结构

IM协议的设计从纵向来看分为三个层次,应用层/安全层/传输层。

应用层

有很多开源协议,例如MQTT,websocket等等。但是这些协议冗余的字段比较多,在大型IM的场景下一般都是自定义协议的。

因此HubuIM采用自定义协议

序列化方式使用protobuf,这个是无可争议的。

安全层

基于密钥的生命周期可以分为

  • TLS/SSL:加密效果好,证书的管理比较复杂

  • 固定加密:通信前客户端和服务端约定好密钥和加密算法(会被黑客逆向)

  • 一人一密:使用用户特定的属性进行加密,例如密码

  • 一次一密:这个是最安全的,创建连接建立一次会话,双方进行加密三次握手(非对称),对称加密传输。

加密消耗的是CPU资源,是CPU密集型操作。如果放到接入层或者业务逻辑层来做的话,会影响到他们的正常运行。因此应该在四层网络负载或者七层网络负载的地方去解密,内网环境默认是安全的。

 

因此HubuIM采用的方式是TLS3.0+网关终止

在Nginx处就进行解密,Nginx所在的机器可以使用硬件来进行优化,例如用GPU加速,用Intel加速器等等。

那么为什么不在LVS(四层网络负载均衡器)上面去做加密解密,然后直接发到IM网关,这样可以让网络通信少跳一次。

这个问题是因为Nginx这个七层负载均衡的地方相当于是公司的一个基础架构层,是要做很多事情的,不方便去掉的。

传输层

可以使用UDP或者TCP协议。微信这种很定义的可能使用UDP+QUIC这种保证可靠性。因为UDP是无状态的传输协议,不会存储连接的状态,在弱网环境下更优,消息风暴发生的可能性更小。

UDP的话需要在应用层写大量的代码来保证可靠性,难度非常大,因此HubuIM使用TCP协议。弱网环境在应用层来进行优化。

总结

HubuIM协议

对于传输层使用TCP,安全层使用TLS,应用层使用自研二进制协议+开源序列化协议。

既然使用了TCP协议,那么我们面临的一个问题就是TCP的粘包,拆包问题。具体解决方法我们在后面讲解。

消息可用性

基本概念

  • 长链接 vs 短链接。我们才用的是长链接和短链接共同作用,短链接作为旁路。

  • 各种ID

    • connID:代表的是一个TCP链接

    • clientID:代表的是client发送给IM Server的用来标识本客户端消息发送顺序的ID,仅仅是本客户端,该ID并不代表消息的全局一致。需要有递增性质。

    • seqID:当IM Server收到clientID之后生成的会话内消息顺序一致的seqID。需要有递增性质。

    • sessionID:会话ID

    • msgID:代表的是一个消息的ID

  • PULL 与 PUSH 模式。PULL就是client向IM Server拉取消息,使用短链接减少TCP链接的压力。PUSH就是IM Server通过TCP长链接推送消息。

  • 通信复杂度:网络传输过程中经过的节点可以说是一个性能瓶颈,不能经过太多节点。消息风暴就是网络中有太多的报文,会压垮IDC。常见于弱网环境,弱网下消息丢失严重,TCP的可靠性反而成为延迟,让网络中有大量的报文。

背景介绍

对于IM来说,消息的可靠与一致就是:可达有序,不重不漏。

有人会问:TCP已经保证一致性了,那么为什么IM还有保证一致。

其实答案很简单:TCP只能保证到内核传输层为止的可靠性,但是应用层的可靠性你是没有办法保证的。

设计IM必须有端到端的设计思维:底层可靠不等于上层可靠,底层一致不等于上层一致

方案选型

技术挑战是什么?

  • 三方通信,网络层面无法保证消息必达

  • 没有全局时钟,确定唯一顺序,并且是符合因果顺序的

  • 多客户发送/多服务端接收/多线程多协程处理,顺序难以确定。

解决方案是学习TCP:

  • 消息及时:服务端实时接收消息并实时在线发送

  • 消息可达:超时重试,ACK确认

  • 消息幂等:分配seqID,服务端存储seqID

  • 消息有序:seqID可以比较。

上行消息

clientID严格递增

弱网问题是传输层的问题,可以优化传输层协议,例如升级成Quic来优化,长连接不适合在弱网环境下工作。

消息转发

  • seqID在会话内有序就行,这样就可以解决redis的单点问题。

  • seqID需要在ACK之前分配,否则ACK成功发出去之后,服务器宕机了,这样seqID就等于没有分配,会出现问题。

  • 如果服务端在存储消息,业务处理,接入层路由的时候失败怎么办?

    • 消息存储之后再回复ACK,如果ACK失败则客户端重试时再次幂等的回复ACK。

    • 一旦消息存储,如果服务崩溃导致长连接断开,客户端重新建立连接时可以发送一个pull信令,拉去历史消息进行消息补洞,保证可靠性。

  • 消息存储可以交给MQ异步的进行。

下行消息

分配seqID的时候针对redis的单点使用lua脚本来进行一个ID的跳变。

客户端发现消息不连续的时候可能是因为消息跳变了,但是他无法确认,因此不能直接拒绝,而是发送pull信令来进行增补,如果拉去不到新消息则说明是跳变导致。

推拉结合+长短连接结合+服务端打包整流:假如是一个群聊,一下子有100M信息,我会把这些信息放在一个窗口里面,不会一个一个发送,这样的批处理可以提高效率。然后窗口大了之后服务端向客户端发送一个pull信令,让客户端发起一个请求来用短链接拉取这个窗口里面的数据。

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

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

相关文章

Qt应用开发(拓展篇)——示波器/图表 QCustomPlot

一、介绍 QCustomPlot是一个用于绘图和数据可视化的Qt C小部件。它没有进一步的依赖关系,提供友好的文档帮助。这个绘图库专注于制作好看的,出版质量的2D绘图,图形和图表,以及为实时可视化应用程序提供高性能。 QCustomPl…

温湿度传感器之Modbus TCP相比较Modbus RTU的优势

1) 当多个网关共同接一个后台服务器,而一个网关下挂接多个485设备时,如果不同的网关挂接同样地址号的485设备时那么后台服务器无法区分是哪个485从设备,并且最多只能限制485设备个数254个,而modbus-tcp协议包含自定义报文头4个字节…

什么是NetDevOps

NetDevOps 是一种新兴的方法,它结合了 NetOps 和 DevOps 的流程,即将网络自动化集成到开发过程中。NetDevOps 的目标是将虚拟化、自动化和 API 集成到网络基础架构中,并实现开发和运营团队之间的无缝协作。 开发运营(DevOps&…

网站和API支持HTTPS,最好在Nginx上配置

随着我们网站用户的增多,我们会逐渐意识到HTTPS加密的重要性。在不修改现有代码的情况下,要从HTTP升级到HTTPS,让Nginx支持HTTPS是个很好的选择。今天我们来讲下如何从Nginx入手,从HTTP升级到HTTPS,同时支持静态网站和…

GEE-PIE遥感大数据处理技术

随着航空、航天、近地空间等多个遥感平台的不断发展,近年来遥感技术突飞猛进。由此,遥感数据的空间、时间、光谱分辨率不断提高,数据量也大幅增长,使其越来越具有大数据特征。对于相关研究而言,遥感大数据的出现为其提…

机器学习深度学习——针对序列级和词元级应用微调BERT

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——NLP实战(自然语言推断——注意力机制实现) 📚订阅专栏:机…

独立站怎么搭建?看这一篇就够了!强烈建议收藏!

独立站是跨境卖家对外销售的一个重要渠道,也是品牌塑造和品牌宣传的重要阵地。那么新手如何从0到1搭建出一个属于自己的独立站呢? 01.购买域名: 域名就相当于是一个网站的门牌号,是独立站的重要组成部分。卖家可以选择自己注册&…

C语言:指针(超深度讲解)

目录 指针: 学习目标: 指针可以理解为: 字符指针: 定义:字符指针 char*。 字符指针的使用: 练习: 指针数组: 概念:指针数组是一个存放指针的数组。 实现模拟二维…

【0基础入门Python Web笔记】四、python 之计算器的进阶之路

四、python 之计算器的进阶之路 往期导航越来越智能的加法计算器加减乘除计算器来点课程作业?更多实战项目可进入下方官网 往期导航 一、python 之基础语法、基础数据类型、复合数据类型及基本操作 二、python 之逻辑运算和制流程语句 三、python 之函数以及常用内…

服务器中了Cylance勒索病毒,数据该怎么恢复?

近日,在市面上出现了一种名为Cylance的勒索病毒。经过云天数据恢复中心技术工程师对比分析后发现,该病毒不属于已知的任何勒索病毒家族中的成员,属于一种新型的勒索病毒,那接下来我们分析一下这种勒索病毒。 中了Cylance勒索病毒的…

AVL树Java实现

文章目录 AVL树(平衡二插搜索树)1.概念二插搜索树AVL树的基本概念 2.AVL数的实现定义AVL树AVL树的插入AVL树的旋转右单旋左单旋左右双旋右左双旋 删除元素 3. 验证AVL树4.AVL树性能分析 AVL树(平衡二插搜索树) 1.概念 二插搜索树 要想了解AVL树,就得先知道二插搜…

HIDS-wazuh 的配置和防御

目录 安装wazuh 常用内容 检测sql注入 主动响应 安装wazuh 本地测试的话建议用ova文件,直接导入虚拟机就能用了 官网:Virtual Machine (OVA) - Installation alternatives 常用内容 目录位置:/etc/ossec 配置文件&…

装箱和拆箱

1. 概念 装箱 将值类型转换成等价的引用类型 装箱的步骤 拆箱 将一个已装箱的引用类型转换为值类型,拆箱操作需要声明拆箱后转换的类型 拆箱的步骤 1)获取已装箱的对象的地址 2)将值从堆上的对象中复制到堆栈上的值变量中 2. 总结 装箱和拆箱…

表现层消息一致性处理

设计表现层返回结果的模型类, 用于后端与前端进行数据格式统一,也称为前后端数据协议 Data public class R {private Boolean flag;private Object data;private String msg;public R(){}public R(Boolean flag){this.flag flag;}public R(Boolean fla…

如何使用NLP库解析Python中的文本

Python是一种强大的面向对象的编程(object-oriented programming,OOP)语言,在人工智能领域有着广泛的用途。正是鉴于其实用性,以Google为首的大型科技公司,已经对其开发了Tensorflow等代码库,帮…

相交链表00

题目链接 相交链表 题目描述 注意点 保证 整个链式结构中不存在环函数返回结果后,链表必须 保持其原始结构如果 listA 和 listB 没有交点,intersectVal 为 0 解答思路 两个链表从头开始遍历,如果其是在同一个位置处相交,则在…

(AcWing)没有上司的舞会

Ural 大学有 NN 名职员,编号为 1∼N。 他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。 每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N。 现在要召开一场周年庆宴会,不过,没有职…

智能问答FAQ的原始问答数据怎么整理?

整理智能问答FAQ的原始数据是构建一个智能问答系统的重要步骤之一。 如何整理原始问答数据以及如何将其转化为智能问答系统 1. 收集原始数据 收集原始数据是整理智能问答FAQ的第一步。可以从以下途径收集原始数据: 网络搜索:通过搜索引擎、论坛、社交…

小白到运维工程师自学之路 第七十九集 (基于Jenkins自动打包并部署Tomcat环境)2

紧接上文 4、新建Maven项目 clean package -Dmaven.test.skiptrue 用于构建项目并跳过执行测试 拉到最后选择构建后操作 SSH server webExec command scp 192.168.77.18:/root/.jenkins/workspace/probe/psi-probe-web/target/probe.war /usr/local/tomcat/webapps/ /usr/loca…

伦敦银和伦敦金的区别

伦敦银河伦敦金并称贵金属交易市场的双璧,一般投资贵金属的投资者其实不是交易伦敦金就是交易伦敦银。相信经过一段时间的学习和投资,不少投资者都能分辨二者的区别。下面我们就来谈谈伦敦银和伦敦金有什么异同,他们在投资上是否有差别。 交易…