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.如何保证双方消息顺序一致?
如果收到的消息有序,那么双方消息的顺序自然会一致
标签:seq,即时通讯,保证,消息,有序,msg,序列号,id,客户端 From: https://blog.csdn.net/2303_77208351/article/details/143103867