首页 > 其他分享 >即时通讯:消息如何保证有序?

即时通讯:消息如何保证有序?

时间:2024-10-22 19:17:43浏览次数:10  
标签:seq 即时通讯 保证 消息 有序 msg 序列号 id 客户端

1.消息如何保证有序?

参考:http://www.52im.net/thread-714-1-1.html

消息有序即 发送的顺序和收到的顺序一致

消息头字段内容包括:发送方id,接收方id,消息msg_id,消息类型,创建时间,大小等

message IMMsgData {
	cmd id: 0x0301  // 消息数据指令ID
	
    uint32 from_user_id = 1;  // 消息发送方的用户ID
	uint32 to_session_id = 2;  // 消息接收方的会话ID(如聊天会话ID)
	uint32 msg_id = 3;  // 消息ID,用于唯一标识这条消息
	
    uint32 create_time = 4;  // 消息创建时间,时间戳形式
	IM.BaseDefine.MsgType msg_type = 5;  // 消息类型,例如文本、图片、视频等
	
    bytes msg_data = 6;  // 消息内容的实际数据
}

方案一,强一致性

  • 客户端发送消息时,消息头有seq_num字段用来做消息确认(丢失重传),服务端收到消息会回复ack

  • 当然seq_num也标识着客户端消息的顺序,服务端若要保证消息有序,要根据每个客户端消息的seq顺序来递增分配全局唯一的msg_id

  • 各客户端之间的seq可以重复,因为对各个客户端来说seq是用来做本端的消息确认和消息顺序的,对服务端来说,各客户端之间有不同的客户端标识

**问题:使用客户端的seq会造成队头阻塞问题,即seq=1的消息不到达会阻塞后面的消息 **

方案二,性能优先

目前采用的是这种方式,也就是不根据seq判断顺序,seq只做消息确认,谁先到就先分配msg_id,缺点是偶尔会消息乱序

消息序列号怎么生成?

参考:http://www.52im.net/thread-1998-1-1.html

单机场景

单机使用一个全局递增的消息序列号,为每条消息分配唯一的序列号

分布式场景

分布式场景中如果每台服务器使用本地的全局序列号,那么会出现序列号冲突

解决方案

1.首先考虑的是确保每条消息的序列号唯一性,使用用户id+本地序列号,但这只使用于单聊,在群聊中用户id失效,序列号仍然会重复

2.时间戳的方式,无法保证所有服务器的时间同步,弃用

3.消息队列,复杂,延迟

4.使用全局唯一递增序列号,需要使用一个独立的服务,由于是单点(避免分布式的同步问题),对性能要求高(微信使用此方式

优化

对于全局的消息id分配,可以将单聊和群聊分开,以减少单点服务的压力

2.如何保证双方消息顺序一致?

如果收到的消息有序,那么双方消息的顺序自然会一致

点击获取更多Linux C/C++开发学习资料

标签:seq,即时通讯,保证,消息,有序,msg,序列号,id,客户端
From: https://blog.csdn.net/2303_77208351/article/details/143103867

相关文章

  • 将有序数组转换为二叉搜索树
    给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。示例1:输入:nums=[-10,-3,0,5,9]输出:[0,-3,9,-10,null,5]解释:[0,-10,5,null,-3,null,9]也将被视为正确答案:示例2:输入:nums=[1,3]输出:[3,1]解释:[1,null,3]和[3......
  • 分布式缓存的基本概念入门以及如何保证数据一致性
    一、分布式缓存基本概念和常见技术框架JavaWeb中的分布式缓存是指在多台服务器之间共享缓存数据的技术。在分布式系统中,单个应用实例通常不会运行在一个单一的服务器上,而是部署在多个节点上以实现负载均衡和高可用性。为了在这些节点之间共享数据,就需要使用分布式缓存技术......
  • 代码随想录算法训练营day20| 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树
    学习资料:https://programmercarl.com/0669.修剪二叉搜索树.html#算法公开课学习记录:669.修剪二叉搜索树(直接在原函数上操作,要根据情况用root的左右子树递归,因为子树中有满足条件的;前序:根左右)点击查看代码#Definitionforabinarytreenode.#classTreeNode:#def_......
  • 记录Redis+MQ延迟双删保证缓存一致性
    场景描述在博客系统中,用户可以给博客点赞或者评论,这些操作需要更新数据库中的数据,同时要保证缓存中的博客信息与数据库保持一致。为了提高性能,博客数据会存放在Redis缓存中。但当有大量用户同事点赞或是评论时,缓存和数据库中的数据可能出现不一致。何谓延迟双删?延迟双删......
  • 二叉树和度为二的有序树的区别
    一、定义与结构度为二的有序树:在这种树结构中,每个节点最多有两个子节点。子节点的顺序是重要的,即使两个子节点的值相同,只要他们的位置不同,他们就被视为是不同的子节点。当一个节点只有一个子节点时,该子节点的位置(左或右)并无特定要求,也即无需区分其左右次序。二叉树:二叉树......
  • 109. 有序链表转换二叉搜索树【二叉树】
    文章目录109.有序链表转换二叉搜索树解题思路Go代码109.有序链表转换二叉搜索树109.有序链表转换二叉搜索树给定一个单链表的头节点head,其中的元素按升序排序,将其转换为平衡二叉搜索树。平衡二叉树是指该树所有节点的左右子树的深度相差不超过1。示例......
  • 代码随想录算法训练营第一天|704二分查找、27移除元素、977有序数组的平方
    代码随想录算法训练营第一天|704二分查找、27移除元素、977有序数组的平方1Leetcode704二分查找题目链接:[704.二分查找](704.二分查找-力扣(LeetCode))文章链接:[代码随想录](代码随想录(programmercarl.com))视频链接:[手把手带你撕出正确的二分法|二分查找法|二分搜......
  • 如何保证Redis和数据库的数据一致性
    文章目录0.前言1.补充知识:CP和AP2.什么情况下会出现Redis与数据库数据不一致3.更新缓存还是删除缓存4.先操作缓存还是先操作数据库4.1先操作缓存4.1.1数据不一致的问题是如何产生的4.1.2解决方法(延迟双删)4.1.3最终一致性和强一致性4.1.4如何确定延迟双删的延迟......
  • java模拟量子加密,特别是基于量子密钥分发(QKD)的加密,是一种利用量子力学原理来保证信息
    本人详解作者:王文峰,参加过CSDN2020年度博客之星,《Java王大师王天师》公众号:JAVA开发王大师,专注于天道酬勤的Java开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯山峯转载说明:务必注明来源(注明:作者:王文峰哦)java模拟量子......
  • 保证Mysql数据库的安全性
    数据库安全性的重要性在一个企业中,为了维护企业声誉和客户信任,保护客户信息和公司数据就显得至关重要,再者,确保公司的系统正常运行,也要保证数据不被恶意篡改,还需要抵御外部攻击和内部威胁。防止数据泄露加密:使用SSL/TLS加密传输数据,启用数据加密功能保护存储的数据使用Op......