即时消息技术剖析与实战

news/发布时间2024/5/2 14:44:00

1.架构与特性:一个完整的IM系统是怎样的?

当服务端有消息需要推送给客户端时,也是将经过业务层处理的消息先递交给接入层,再由接入层通过网络发送到客户端。

此外,在很多基于私有通信协议的IM系统实现中,接入服务还提供协议的编解码工作,编解码实际主要是为了节省网络流量,系统会针对传输的内容进行紧凑的编码(比如Protobuf),为了让业务处理时不需要关心这些业务无关的编解码工作,一般由接入层来处理。

另外,还有session维护的工作很多时候也由接入服务来实现,session的作用是标识“哪个用户在哪个TCP连接”,用于后续的消息推送能够知道,如何找到接收人对应的连接来发送。

2.消息收发架构:为你的App,加上实时通信功能?

 

3.轮询与长连接:如何解决消息的实时到达问题?

短轮询和长轮询之所以没法做到基于事件的完全的“边缘触发(当状态变化时,发生一个IO事件)”,这是因为服务端在有新消息产生时,没有办法直接向客户端进行推送。

这里的根本原因在于短轮询和长轮询是基于HTTP协议实现的,由于HTTP是一个无状态协议,同一客户端的多次请求对于服务端来说并没有关系,也不会去记录客户端相关的连接信息。

因此,所有的请求只能由客户端发起,服务端由于并不记录客户端状态,当服务端接收到新消息时,没法找到对应的客户端来进行推送。

4.ACK机制:如何保证消息的可靠投递?

针对第一部分123,我们通过客户端A的超时重发和IM服务器的去重机制,基本就可以解决问题;针对第二部分4,业界一般参考TCP协议的ACK机制,实现一套业务层的ACK协议。

IM服务器在推送消息时,携带一个标识SID(安全标识符,类似TCP的sequenceId),推送出消息后会将当前消息添加到“待ACK消息列表”,客户端B成功接收完消息后,会给IM服务器回一个业务层的ACK包,包中携带有本条接收消息的SID,IM服务器接收后,会从“待ACK消息列表”记录中删除此条消息,本次推送才算真正结束。

超时重传带来的问题是重复推送消息,需要业务方去重。

消息完整性检查

5.消息序号生成器:如何保证你的消息不会乱序?

单机本地化的时钟或者序号都存在问题,那么如果有一个全局的时钟或者序号是不是就能解决这个问题了呢?所有的消息的排序都依托于这个全局的序号,这样就不存在时钟不同步的问题了。

而且这种“全局序号生成器”可以通过多种方式来实现,常见的比如Redis的原子自增命令incr,DB自带的自增id,或者类似Twitter的snowflake算法、“时间相关”的分布式序号生成服务等。

有了“时序基准”,是不是就能确保消息能按照“既定顺序”到达接收方呢?答案是并不一定能做到。原因在于下面两点。

  1. IM服务器都是集群化部署,每台服务器的机器性能存在差异,因此处理效率有差别,并不能保证先到的消息一定可以先推送到接收方,比如有的服务器处理得慢,或者刚好碰到一次GC,导致它接收的更早消息,反而比其他处理更快的机器更晚推送出去。

  2. IM服务端接收到发送方的消息后,之后相应的处理一般都是多线程进行处理的,比如“取序号”“暂存消息”“查询接收方连接信息”等,由于多线程处理流程,并不能保证先取到序号的消息能先到达接收方,这样的话对于多个接收方看到的消息顺序可能是不一致的。

所以一般还需要端上能支持对消息的“本地整流”。

根据包的ID,对一定时间内的消息做一个整流和排序,这样即使服务端处理多条消息时出现乱序,仍然可以在最终推送给客户端时整流为有序的。

 

在即时消息收发场景中,用于保证消息接收时序的序号生成器为什么可以不是全局递增的?

答: 这是由业务场景决定的,这个群的消息和另一个群的消息在逻辑上是完全隔离的,只要保证消息的序号在群这样的一个局部范围内是递增的即可; 当然如果可以做到全局递增最好,但是会浪费很多的资源,却没有带来更多的收益。

6.HttpDNS和TLS:你的消息聊天真的安全吗?

  1. 消息传输安全性。“访问入口安全”和“传输链路安全”是基于互联网的即时消息场景下的重要防范点。针对“访问入口安全”可以通过HttpDNS来解决路由器被恶意篡改和运营商的LocalDNS问题;而TLS传输层加密协议是保证消息传输过程中不被截获、篡改、伪造的常用手段。

  2. 消息存储安全性。针对账号密码的存储安全可以通过“高强度单向散列算法”和“加盐”机制来提升加密密码可逆性;对于追求极致安全性的即时消息场景并且政策允许的情况下,服务端应该尽量不存储消息内容,并且采用“端到端加密”方式来提供更加安全的消息传输保护。

  3. 消息内容安全性。针对消息内容的安全识别可以依托“敏感词库”“图片识别”“OCR和语音转文字”“外链爬虫抓取分析”等多种手段,并且配合“联动惩罚处置”来进行风险识别的后置闭环。

7.分布式锁和原子性:你看到的未读消息提醒是真的吗?

 

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

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

相关文章

实验报告3

项目一 解题思路 1.用char函数定义字符 2.scanf函数输入三个字母 3.用a-32表示对应的大写字母 核心代码 #include <stdio.h>int main(){ char a,b,c;scanf("%c,%c,%c",&a,&b,&c);printf("%c的ASCII值:%d 大写字母:%c\n",a,a,a-32);pri…

CNCKAD数冲激光编程排版软件介绍

CNCKAD是一种集成了CAD和CNC的软件,它可以导入各种图形和CAD文件格式,比如DXF、DWG和IGES,帮助用户创建复杂的3D模型、独特的几何形状和特殊的设计要求。CNCKAD的核心功能是自动化的刀具路径生成,它可以通过多种方式生成刀具路径,包括手动、自动、半自动和机器学习等方法,…

Go 实战|使用 Wails 构建轻量级的桌面应用:仿微信登录界面 Demo

Wails 框架提供了一种简洁而强大的方式,让开发者能够利用 Go 的性能优势和 Web 前端的灵活性,从而能够使用更高效、更轻量级的方法来构建跨平台的桌面应用。本文探讨 Wails 框架的使用,从搭建环境到开发,再到最终的构建打包。概述 本文探讨 Wails 框架的使用,从搭建环境到…

笛卡尔树

1 定义 笛卡尔树是一种二叉树,每一个节点由二元组 \((k,w)\) 组成。要求 \(k\) 满足二叉搜索树的性质,\(w\) 满足堆的性质。 当 \(k,w\) 都确定,且 \(k,w\) 互不相同时,笛卡尔树的结构是唯一的,如图:看到这个定义,会发现与 Treap 十分相似。 实际上,Treap 就是一种特殊…

开源软件

接触编程之后难免会接触到开源的软件,起初觉得很奇怪,这么复杂且封装良好的软件为什么作者会平白无故分享出来?比如一些免费开源的CMS建站系统,当时可是我做网络维护岗位时最喜欢翻弄的东西了,后来随着了解的深入,渐渐发现,其实这些工具面向的除了标准的用户群体,还有一群渴望…