热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

融云发送图片消息_IM消息同步机制全面解析

一、综述即时通讯系统最基础、最重要的是消息的及时性与准确性,及时体现在延迟,准确则具体表现为不丢、不重、不乱序。综合考虑业务场景、系统复杂度、网络流量、

一、综述

即时通讯系统最基础、最重要的是消息的及时性与准确性,及时体现在延迟,准确则具体表现为不丢、不重、不乱序。

综合考虑业务场景、系统复杂度、网络流量、终端能耗等,融云精心设计了消息收发机制,并不断打磨优化,形成了现在的消息同步机制。

整体思路:1.客户端、服务端共同配合,互相补充。2.采用多重机制,从不同层面保障。3.拆分上下行,分别处理。

二、协议层

首先,从协议层保证,协议栈需要提供可靠、有序的双向字节流传输,融云自研通信协议 RMTP(RongCloud Message Transfer Protocol)。

27fd08420df45b7640c74318b8ec31ec.png

协议交互示意图

协议层通过 qos、 ack 等机制,保证数据传输的可靠性。

三、业务层

在关键业务,采用 ack 确认机制,配合状态机,服务感知当前业务传输状态,保障业务按照预期执行。

3fdd0e881f6bad4d01230abc1f980d06.png

业务层确认机制示意图

消息 ID

采用全局唯一的消息 ID 生成策略。保证消息可通过 ID 进行识别,排重。

ef7bc3e663d283dea396039351f788c7.png

如何实现分布式场景下唯一 ID 生成,请关注融云了解。

客户端服务端交互

客户端与服务端之间使用长连接,基于 RMTP 协议传输数据。经过总结,主要用三种行为:

1.客户端主动拉取消息,主动拉取有两个触发方式:①与 IM 服务新建立连接成功,用于获取不在线的这段时间未收到的消息。(此处叫做获取离线消息)②定时器触发。在客户端最后收到消息后启动定时器,比如 3-5 分钟执行一次, 主要有两个目的,一个是用于防止因网络,中间设备等不确定因素引起的通知送达失败,服务端客户端状态不一致,一个是可通过本次请求,对业务层做状态机保活。

2.服务端主动-发送消息(直发消息) 在线消息发送机制之一,简单理解为服务端将消息内容直接发送给客户端,适用于消息频率较低,并且持续交互,比如二人或者群内的正常交流讨论。

3、服务端主动-发送通知(通知拉取) 在线消息发送机制之一,简单理解为服务端给客户端发送一个通知,通知包含时间戳等可作为排序索引的内容,客户端收到通知后,依据自身数据,对比通知内时间戳,发起拉取消息的流程。适用于较多消息传递。比如某人有很多大规模的群,每个群内都有很多成员正在激烈讨论。通过通知拉取机制,可以有效的减少客户端服务端网络交互次数,并且对多条消息进行打包,提升有效数据载荷。既能保证时效,又能保证性能。

73ffeca9d97b4df9c012899ae2e376ec.png

客户端服务端交互示意图

业务拆分

在有了多层机制保证后,将业务进行拆分,首先将业务拆分出上下行,在上行过程保证发送消息顺序,为了保证消息有序, 最好的方式是按照 userId 区分,然后使用时间戳排序。那么分布式部署情况下,将用户归属到固定的业务服务器上,会使得上行排序变得更容易。同时归属到同一个服务器,在多端维护时也更容易。

客户端连接过程1.客户端通过 APP server ,获取到连接使用的 token。2.客户端使用 token 通过导航服务,获取具体连接的 IM 接入服务器(CMP),导航服务通过 userId 计算接入服务器,然后下发,使得某一客户端可以连接在同一台接入服务器(CMP)。

03dcc25ac66085b308b9d48d9b265abf.png

示意图

上行

客户端发出消息后,通过接入服务,按照 userId 投递到指定消息服务器,生成消息 Id, 依据最后一条消息时间,确认更新当前消息的时间戳(如果存在相同时间戳则后延),然后将时间戳,以及消息 Id,通过 Ack 返回给客户端 ; 然后对上行消息使用 userId + 时间戳进行缓存以及持久化存储,后续业务操作均使用此时间戳。(此业务流程我们成为上行流程,上行过程存储的消息为发件箱消息)

下行

消息节点在处理完上行流程后,消息按照目标用户投递到所在消息节点,进入下行流程。下行过程,按照目标 userId 以及本消息在上行过程中生成的时间戳,计算是否需要更新时间戳(正向)。如果需要更新则对时间戳进行加法操作,直到当前用户时间戳不重复。如此处理后,目标用户的存储以及客户端接收到消息后的排重可以做到一致,并且可以做到同一个会话内的时间戳是有序的。从而保证同一个接收用户的消息不会出现乱序。

至此,我们已经完成了发送过程,接收过程的消息顺序保障,那么消息流程还剩下直发与通知拉取的处理流程,以及服务端如何选择是直发还是通知拉取。

直发消息

1、客户端 SDK 依据本地存储的最新消息时间戳判断,用来做排序等逻辑。2、对同一个用户直发消息1条,其他转通知。通知拉取时候客户端选择本地最新一条消息时间戳作为开始拉取时间。3、在消息发送过程中,如果上一条消息发送流程未结束,下一条消息则不用直发(s_msg),而是用(s_ntf)

3b5e8a1353d13aee560cfd080a36634f.png

直发逻辑示意图

通知拉取

1.服务端在通知体中携带当前消息时间戳。投递给客户端。2.客户端收到通知后,比对本地消息时间戳,选择是否发拉取消息信令。3.服务端收到拉取消息信令后,以信令携带的时间戳为开始,查询出消息列表(200 条或者 5M),并给客户端应答。4.客户端收到后,给服务端 ack,服务端维护状态。5.客户端拉取消息时使用的时间戳,是客户端本地最新一条消息的时间戳。

27b3fa09f6454a906516bfedfd91c061.png

示意图

上图中,3-7 步可能需要循环多次,有以下考虑: 1.客户端一次收到的消息过多,应答体积过于庞大,传输过程对网络质量要求更高, 因此按照数量以及消息体积分批次进行。2. 一次拉取到的消息过多,客户端处理会占用大量资源,可能会有卡顿等,体验较差。

服务端直发消息与通知拉取切换逻辑

主要涉及到的是状态机的更新。下面示意图集成直发消息与通知拉取过程针对状态机的更新:

5b844aa105a919b8f5d9f0e957958839.png

至此,消息收发核心流程介绍完毕,只剩下多端在线的处理。

四、多端在线同步

多端按照上下行,同样区分为发送方多端同步以及接收方多端同步。

发送方多端同步

在前面客户端连接 IM 服务过程中,我们已经将同一个用户的客户端汇聚在了同一台服务,那么维护一个 userId 的多端就会变得很简单。

1.用户多个终端链接成功后,发送一条消息,这个消息到达 CMP(IM 接入服务) 后,CMP 做基础检查,然后获此用户的其他终端连接。

2.服务把客户端上行的消息,封装为服务端下行消息,直接投递给用户的其他客户端。这样完成了发送方的多端抄送,然后将这条消息投递到 IM 服务。进入正常发送投递流程。发送方的多端同步没有经过 IM Server,这么做的好处是:1.比较快速;2.经过越少的服务节点,出问题的几率越小。

接收方多端同步

1.IM 服务收到消息后,先判断接收方的投递范围,这个范围指的是接收方用户的哪些的终端要接收消息。

2.IM 服务将范围以及当前消息,发送到 CMP,CMP 依据范围,匹配接收方的终端,然后投递消息。

区分接收方多端范围应用场景: 消息一般是所有终端。

有一些特殊业务,比如我在 A 客户端上,控制另外某个端的状态,可能需要一些命令消息, 这时候需要这个作用范围,针对性的投递消息。

14a39b2e41d308c742e9b1ab944ea89f.png

到此,我们分析完了有关 IM 消息核心处理流程,通过层层拆解逻辑,提供可靠的消息投递机制。



推荐阅读
  • 本文推荐了六款高效的Java Web应用开发工具,并详细介绍了它们的实用功能。其中,分布式敏捷开发系统架构“zheng”项目,基于Spring、Spring MVC和MyBatis技术栈,提供了完整的分布式敏捷开发解决方案,支持快速构建高性能的企业级应用。此外,该工具还集成了多种中间件和服务,进一步提升了开发效率和系统的可维护性。 ... [详细]
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 本文深入探讨了 Git 与 SVN 的高效使用技巧,旨在帮助开发者轻松应对版本控制中的各种挑战。通过详细解析两种工具的核心功能与最佳实践,读者将能够更好地掌握版本管理的精髓,提高开发效率。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • Kafka 是由 Apache 软件基金会开发的高性能分布式消息系统,支持高吞吐量的发布和订阅功能,主要使用 Scala 和 Java 编写。本文将深入解析 Kafka 的安装与配置过程,为程序员提供详尽的操作指南,涵盖从环境准备到集群搭建的每一个关键步骤。 ... [详细]
  • 本文详细介绍了如何在Java Web服务器上部署音视频服务,并提供了完整的验证流程。以AnyChat为例,这是一款跨平台的音视频解决方案,广泛应用于需要实时音视频交互的项目中。通过具体的部署步骤和测试方法,确保了音视频服务的稳定性和可靠性。 ... [详细]
  • 第二章:Kafka基础入门与核心概念解析
    本章节主要介绍了Kafka的基本概念及其核心特性。Kafka是一种分布式消息发布和订阅系统,以其卓越的性能和高吞吐量而著称。最初,Kafka被设计用于LinkedIn的活动流和运营数据处理,旨在高效地管理和传输大规模的数据流。这些数据主要包括用户活动记录、系统日志和其他实时信息。通过深入解析Kafka的设计原理和应用场景,读者将能够更好地理解其在现代大数据架构中的重要地位。 ... [详细]
  • TCP三次握手过程详解与图示解析
    本文详细解析了TCP三次握手的过程,并通过图示清晰展示了各个状态的变化。同时,文章还介绍了四次挥手的图解,解释了在TIME_WAIT状态中,客户端最后一次发送的ACK包的作用和重要性。 ... [详细]
  • 本文详细介绍了如何安全地手动卸载Exchange Server 2003,以确保系统的稳定性和数据的完整性。根据微软官方支持文档(https://support.microsoft.com/kb833396/zh-cn),在进行卸载操作前,需要特别注意备份重要数据,并遵循一系列严格的步骤,以避免对现有网络环境造成不利影响。此外,文章还提供了详细的故障排除指南,帮助管理员在遇到问题时能够迅速解决,确保整个卸载过程顺利进行。 ... [详细]
  • 探讨上传下载 API 的常见问题及解决方案 ... [详细]
  • FastDFS Nginx 扩展模块的源代码解析与技术剖析
    FastDFS Nginx 扩展模块的源代码解析与技术剖析 ... [详细]
  • 在Kubernetes上部署多个Mitmproxy代理服务器以实现高效流量管理 ... [详细]
  • 构建高可用性Spark分布式集群:大数据环境下的最佳实践
    在构建高可用性的Spark分布式集群过程中,确保所有节点之间的无密码登录是至关重要的一步。通过在每个节点上生成SSH密钥对(使用 `ssh-keygen -t rsa` 命令并保持默认设置),可以实现这一目标。此外,还需将生成的公钥分发到所有节点的 `~/.ssh/authorized_keys` 文件中,以确保节点间的无缝通信。为了进一步提升集群的稳定性和性能,建议采用负载均衡和故障恢复机制,并定期进行系统监控和维护。 ... [详细]
  • 分布式开源任务调度框架 TBSchedule 深度解析与应用实践
    本文深入解析了分布式开源任务调度框架 TBSchedule 的核心原理与应用场景,并通过实际案例详细介绍了其部署与使用方法。首先,从源码下载开始,详细阐述了 TBSchedule 的安装步骤和配置要点。接着,探讨了该框架在大规模分布式环境中的性能优化策略,以及如何通过灵活的任务调度机制提升系统效率。最后,结合具体实例,展示了 TBSchedule 在实际项目中的应用效果,为开发者提供了宝贵的实践经验。 ... [详细]
  • C#微信开发入门教程第二篇:新手快速上手指南,含详细视频讲解
    在距离上次课程一个多星期后,我们终于带来了第二讲的内容。虽然原计划是一周一次更新,但由于工作繁忙有所延迟。近期在交流群中发现,一些初学者已经能够熟练调用微信接口,但对微信公众平台的消息接收处理机制还不够了解。因此,本次课程将详细介绍如何高效处理微信公众平台的消息接收,并提供详细的视频讲解,帮助大家快速上手。 ... [详细]
author-avatar
zongnaxxl240
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有