自研分布式IM-HubuIM RFC草案

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.mzph.cn/news/49936.shtml

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

相关文章

最新AI系统ChatGPT程序源码/微信公众号/H5端+搭建部署教程+完整知识库

一、前言 SparkAi系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。 那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧&#xff01…

二级MySQL(五)——完整性约束练习

在MYSQL中,通常用来指定一个已有数据库作为当前数据库的语句是【USE】 下列选项中不是MYSQL中常用数据类型的是【VAR】 在MYSQL中,常用【NULL】表示一个字段没有值或缺值 在CREATE TABLE语句中,通常使用【PRIMARY KEY】关键字来指定主键 …

IoT DC3 是一个基于 Spring Cloud 的开源的、分布式的物联网(IoT)平台本地部署步骤

dc3 windows 本地搭建步骤: ​​ 必要软件环境 进入原网页# 务必保证至少需要给 docker 分配:1 核 CPU 以及 4G 以上的运行内存! JDK : 推荐使用 Oracle JDK 1.8 或者 OpenJDK8,理论来说其他版本也行; Maven : 推荐…

【视觉SLAM入门】5.2. 2D-3D PNP 3D-3D ICP BA非线性优化方法 数学方法SVD DLT

"养气之学,戒之躁急" 1. 3D-2D PNP1.1 代数法1.1.1 DLT(直接线性变换法)1.1.2. P3P 1.2 优化法BA (Bundle Adjustment)法 2. 3D-3D ICP2.1 代数法2.1.1 SVD方法 2.2 优化(BA)法2.2.2 非线性优化方法 前置事项: 1. 3D-2D PNP 该问题描述为&am…

记录《现有docker中安装spark3.4.1》

基础docker环境中存储hadoop3--方便后续查看 参考: 实践: export JAVA_HOME/opt/apache/jdk1.8.0_333 export SPARK_MASTER_IP192.168.0.220 export SPARK_WORKER_MEMORY4g export SPARK_WORKER_CORES2 export SPARK_EXECUTOR_MEMORY4g export HADOOP_H…

Mongodb两种启动方法

一、命令行启动 1.修改存放数据库的位置 说明:E:\data\mongodb;我在E盘创建的文件夹mongodb mongod --dbpathE:\data\mongodb 2.成功启动 说明:默认端口27017,代表已经启动成功 ,并在mongodb自动创建文件 二、配置项…

华为AR路由器 典型配置案例——以太网交换

目录 Eth-Trunk 例:配置三层链路聚合 组网需求 操作步骤 检查配置结果 配置脚本 VLAN 举例:配置基于接口划分VLAN,实现同一VLAN内的互通(同设备) 组网需求 操作步骤 检查配置结果 配置脚本 举例&#xff…

TCP半连接队列和全连接队列

目录 什么是 TCP 半连接队列和全连接队列? TCP 全连接队列溢出 如何知道应用程序的 TCP 全连接队列大小? 如何模拟 TCP 全连接队列溢出的场景? 全连接队列溢出会发生什么 ? 如何增大全连接队列呢 ? TCP 半连接队列溢出 如何查看 TC…

22款美规奔驰S500升级原厂香氛负离子系统,清香宜人,久闻不腻

奔驰原厂香氛合理性可通过车内空气调节组件营造芳香四溢的怡人氛围。通过更换手套箱内香氛喷雾发生器所用的香水瓶,可轻松选择其他香氛。香氛的浓度和持续时间可调。淡雅的香氛缓缓喷出,并且在关闭后能够立刻散去。车内气味不会永久改变,香氛…

Linux 虚拟机安装 hadoop

目录 1 hadoop下载 2 解压hadoop 3 为 hadoop 文件夹改名 4 给 hadoop 文件夹赋权 5 修改环境变量 6 刷新环境变量 7 在hadoop313目录下创建文件夹data 8 检查文件 9 编辑 ./core-site.xml文件 10 编辑./hadoop-env.sh文件 11 编辑./hdfs-site.xml文件 12 编辑./mapr…

【C++入门到精通】C++入门 —— 模版(template)

阅读导航 前言一、模版的概念二、函数模版1. 函数模板概念2. 函数模板定义格式3. 函数模板的原理4. 函数模版的实例化🚩隐式实例化🚩显式实例化 5. 函数模板的匹配原则 三、类模板1. 类模板的定义格式2. 类模板的实例化 四、非类型模板参数1. 概念2. 定义…

动态规划之路径问题

路径问题 1. 不同路径(medium)2. 不同路径II(medium)3. 礼物最大值(medium)4. 下降路径最小和(medium)5. 最⼩路径和(medium)6. 地下城游戏(hard&…

图床项目进度(一)——UI首页

1. 前言 前面我不是说了要做一个图床吗,现在在做ui。 我vue水平不够高,大部分参考b站项目照猫画虎。 vue实战后台 我使用ts,vite,vue3进行了重构。 当然,我对这些理解并不深刻,许多代码都是游离于表面&am…

基于决策树(Decision Tree)的乳腺癌诊断

决策树(DecisionTree)学习是以实例为基础的归纳学习算法。算法从--组无序、无规则的事例中推理出决策树表示形式的分类规则,决策树也能表示为多个If-Then规则。一般在决策树中采用“自顶向下、分而治之”的递归方式,将搜索空间分为若千个互不相交的子集,在决策树的内部节点(非叶…

Spring事务和事务传播机制

目录 一. Spring 中事务的实现 1. 编程式事务 2. 声明式事务 3. Transaction 参数的设置 4. Transaction 的隔离级别 5. Transaction 的工作原理 二. Spring 事务传播机制 七种事务传播机制 支持当前事务 不支持当前事务 嵌套事务 一. Spring 中事务的实现 1. 编程式事…

mmdetection基于 PyTorch 的目标检测开源工具箱 入门教程

安装环境 MMDetection 支持在 Linux,Windows 和 macOS 上运行。它需要 Python 3.7 以上,CUDA 9.2 以上和 PyTorch 1.8 及其以上。 1、安装依赖 步骤 0. 从官方网站下载并安装 Miniconda。 步骤 1. 创建并激活一个 conda 环境。 conda create --name…

Docker是什么?详谈它的框架、使用场景、优势

作者:Insist-- 个人主页:insist--个人主页 作者会持续更新网络知识和python基础知识,期待你的关注 目录 一、什么是 Docker? 二、Docker 的架构 1、Docker客户端 2、Docker守护进程 3、Docker镜像 4、Docker容器 5、Docker…

【业务功能篇76】微服务网关路由predicates断言条件-filters路由转换地址-跨域问题-多级目录树化层级设计-mybatisPlus逻辑删除

业务开发-基础业务-分类管理 启动renren-fast如果出现如下错误 -Djps.track.ap.dependenciesfalse 添加相关配置即可 分类管理 1.后端分类接口 JDK8特性:https://blog.csdn.net/qq_38526573/category_11113126.html 在后端服务中我们需要查询出所有的三级分类信…

汽车摩托车零部件出口管理ERP解决方案

近年来,随着全球经济的发展,人们对交通工具的需求增加,国内汽车、摩托车市场的不断扩大,以及国内制造技术的不断提高,中国汽车、摩托车零部件出口业务迎来了广阔的发展前景,带动了汽车配件和摩托车配件市场…

分布式下的session共享问题

首页我们确定在分布式的情况下session是不能共享的。 1.不同的服务,session不能共享,也就是微服务的情况下 2.同一服务在分布式情况,session同样不能共享,也会是分布式情况 分布式下session共享问题解决方案(域名相同) 1.session复…