聊天消息怎样做到不丢失、不重复、不乱序?离线期间的消息怎样补上?
先自己想一想,再看参考要点
参考要点
- 不丢、不重:发送方为每条消息生成 msg_id,服务端存储后回复 ACK,超时没收到就用同一个 msg_id 重发,服务端用 (sender_id, msg_id) 唯一索引去重
- 不乱序:服务端为每个会话分配递增的 seq,接收方按 seq 排序,不按各机器的时间
- 离线:推送只负责通知,接收方记住连续收齐的最大 seq(例如 58),重连时拉取它之后的消息,收到 61 而本地只到 58 时补拉中间的 59、60
- 用 INCR 分配 seq 时写入失败会留下补不到的空号,后分配的也可能先写入,要求序号连续时在一个事务中把会话的最大序号加 1 并插入消息