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

自研分布式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信令,让客户端发起一个请求来用短链接拉取这个窗口里面的数据。

相关文章:

自研分布式IM-HubuIM RFC草案

HubuIM RFC草案 消息协议设计 基本协议 评估标准 【性能】协议传输效率,尽可能降低端到端的延迟,延迟高于200ms用户侧就会有所感知 【兼容】既要向前兼容也要向后兼容 【存储】减少消息包的大小,降低空间占用率,一个字节在亿…...

tableau基础学习1:数据源与绘图

文章目录 读取数据常用绘图方法1. 柱状图2. 饼图3. 散点图4. 热力图 第一部分是一些较容易上手的内容,以及比较常见的可视化内容,包括:柱状图、饼图、散点图与热力图 读取数据 打开界面后,选择数据源之后就可以导入数据&#xf…...

探索经典算法问题与解决方案

探索经典算法问题与解决方案 在计算机科学领域,有许多经典算法问题需要我们思考和解决。本文将深入介绍一些著名的经典算法问题,包括旅行商问题、背包问题的变种、N皇后问题、钢条切割问题、最大子数组和问题、最长公共子串问题以及矩阵连乘问题&#x…...

【Linux】DNS系统,ICMP协议,NAPT技术

遏制自己内心的知识优越感,才能让你发自内心的去尊重他人,避免狂妄自大,才能让你不断的丰富自己的内心。 文章目录 一、DNS系统1.DNS服务器返回域名对应的ip2.使用dig工具分析DNS过程3.浏览器中输入url后发生的事情? 二、ICMP协议…...

BI技巧丨Window应用之同环比

白茶曾介绍过OFFSET可以用来解决同环比的问题&#xff0c;其实微软最近推出的开窗函数WINDOW也可以用来解决同环比。 WINDOW函数基础语法 WINDOW ( from[, from_type], to[, to_type][, <relation>][, <orderBy>][, <blanks>][, <partitionBy>][, &l…...

【Mac】编译Spring 源码和Idea导入

今天我们开始Spring源码的阅读之旅。阅读Spring的源码的第一步当然是编译Spring源码。首先我们要去GitHub上将spring源码给clone下来。 笔者编译环境如下&#xff1a; Spring版本&#xff1a;5.28 https://github.com/spring-projects/spring-framework/tree/v5.2.8.RELEASE …...

手把手教你用 ANSYS workbench

ANSYS Workbench ANSYS Workbench是一款基于有限元分析&#xff08;FEA&#xff09;的工程仿真软件。其基本概念包括&#xff1a; 工作区&#xff08;Workspace&#xff09;&#xff1a;工程仿真模块都在此区域内&#xff0c;包括几何建模、网格划分、边界条件设置、分析求解等…...

Kotlin开发笔记:协程基础

Kotlin开发笔记&#xff1a;协程基础 导语 本章内容与书的第十五章相关&#xff0c;主要介绍与协程相关的知识。总的来说&#xff0c;本文将会介绍Kotlin中关于异步编程的内容&#xff0c;主要就是与协程有关。在Kotlin中协程是利用continuations数据结构构建的&#xff0c;用…...

自学设计模式(简单工厂模式、工厂模式、抽象工厂模式)

使用工厂模式来生产某类对象&#xff08;代码简化且容易维护&#xff0c;类之间有血缘关系&#xff0c;可以通过工厂类进行生产&#xff09;&#xff1b; 简单工厂模式&#xff08;用于创建简单对象&#xff09; 对于简单工厂模式&#xff0c;需要的工厂类只有一个&#xff1…...

NFS:使⽤ NFS 为远程客户端提供共享文件系统

写在前面 分享一些 nfs 搭建的笔记考试顺便整理内容涉及 nfs 服务端客户端的搭建配置理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&…...

2022-kaggle-nlp赛事:Feedback Prize - English Language Learning(超多注释讲解)

2022-kaggle-nlp赛事&#xff1a;Feedback Prize - English Language Learning 零、比赛介绍 比赛地址Feedback Prize - English Language Learning | Kaggle 0.1 比赛目标 写作是一项基本技能。可惜很少学生能够磨练&#xff0c;因为学校很少布置写作任务。学习英语作为第…...

第十三课 宾语从句

文章目录 前言一、宾语从句1、主语及物动词宾语从句2、主语双宾动词间接宾语直接宾语3、主语特定及物动词宾语从句&#xff08;作宾语&#xff09;宾补4、主语be某些形容词宾语从句5、动词不定式后面的宾语从句6、动名词后面的宾语从句7、介词后面的宾语从句9、间接引语 前言 一…...

Docker容器与虚拟化技术:GitHub账户注册

目录 一、实验 1.GitHub 一、实验 1.GitHub &#xff08;1&#xff09;GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git作为唯一的版本库格式进行托管&#xff0c;故名GitHub。 &#xff08;2&#xff09;官网 GitHub: Let’s build from here …...

thinkphp安装workman

需要加版本&#xff0c;版本太高了不行 composer require topthink/think-worker1.0.*...

L1-036 A乘以B(Python实现) 测试点全过

题目 看我没骗你吧 —— 这是一道你可以在 10 秒内完成的题&#xff1a;给定两个绝对值不超过 100 的整数 A 和 B&#xff0c;输出 A 乘以 B 的值。 输入格式 输入在第一行给出两个整数 A 和 B &#xff08; − 100 ≤ A , B ≤ 100 &#xff09; A 和 B&#xff08;−100≤…...

代码随想录第五十三天

代码随想录第五十三天 Leetcode 1143. 最长公共子序列Leetcode 1035. 不相交的线Leetcode 53. 最大子数组和 Leetcode 1143. 最长公共子序列 题目链接: 最长公共子序列 自己的思路:没想出来&#xff01;&#xff01;&#xff01; 正确思路:首先这道题由于是涉及到了两个数组&…...

cmd - 如何在不重启的情况下让修改后的hosts生效

cmd - 如何在不重启的情况下让修改后的hosts生效 亲测有效 一般在修改了hosts文件后&#xff0c;需要重启电脑才能生效&#xff1b;其实可以不通过重启电脑也可以令其生效&#xff0c;方法如下&#xff1a; 打开cmd窗口输入​​ipconfig /flushdns​​&#xff0c;然后回车。…...

echarts实现双x轴并且分组滚动效果

var myChart echarts.init(document.getElementById(allOutPut1));var option {legend: {itemHeight: 10, // 图例icon高度itemWidth: 16, // 图例icon宽度icon:rect,//设置为矩形top:2%,right:10%,},tooltip: {trigger: axis,axisPointer: {type: shadow},textStyle: {fontS…...

UE4 地形编辑基础知识 学习笔记

之前自己写过这样的功能&#xff0c;今天看到一个UE现成的 点击地形&#xff0c;选择样条 按住CTRL键点击屏幕中某一个点会在场景内生成一个这样的图标 再点两次&#xff0c;会生成B样条的绿线条 点击号再选择一个模型&#xff0c;会生成对应的链条状的mesh 拉高最远处的一个图…...

AcWing算法提高课-5.5.2最大公约数

宣传一下 算法提高课整理 CSDN个人主页&#xff1a;更好的阅读体验 原题链接 题目描述 给定整数 N N N&#xff0c;求 1 ≤ x , y ≤ N 1 \le x,y \le N 1≤x,y≤N 且 gcd ⁡ ( x , y ) \gcd(x,y) gcd(x,y) 为素数的数对 ( x , y ) (x,y) (x,y) 有多少对。 输入格式 输…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...