温馨提示:文本由机器自动转译,部分词句存在误差,以视频为准
00:00
本文是零基础I'M开发入门系列文章的第4篇。什么是I'M聊天系统的消息时序一致性?I'M系统中消息时序的一致性问题是个看似简单实则非常有难度的技术热点话题之一。本文尽量以通俗简显的文字为你讲解I'M消息时序一致性问题的产品意义、发生原因、解决思路等。消息时序的一致性问题对于I'M的意义,毫无疑问,带来的不只是简简单单的所谓用户体验问题。假设你跟女神的表白正进入到关键阶段,聊着聊着,就因为这段I'M,导致聊天消息前言不搭后语,此刻1000km外,你的女神真一脸懵逼的盯着手机看你的醉话,后果是多么严重,这半年来的舔狗生活忍辱负重,算是白白被程序员这群格子山地中海们给祸害了。再往严重了说,就因为这段I'M,让你失去了这难得的借助女神优良基因改造家族后代颜值的。
01:00
绝佳机会无不让人痛心疾首。上面这个例子说了还只是单聊,如果是群聊,则问题可能还会被无限放大。试想一个技术交流群正在激烈的争吵着PHP是世界最好语言这种话题的时候,忽然就想砸手机了,不是因为吵得太凶,而因为消息顺序全乱,完全没法看,已经严重影响键盘侠们积极发表个人意见了。在普通I'M用户的眼里,消息无非是从一台手机传递到另一台手机而已,保证持续有何困难?实际上,在I'M这种高性能场景下,服务端为了追求高吞吐、高并发,用到了多线程、异步IO等等技术。高并发与顺序对于I'M服务端来说本来就是矛盾的,这就有点鱼与熊掌的味道了,两者很难兼得。所以要实现I'M场景下的消息持续一致性需要做出权衡,而且要考虑的技术维度相当多,这就导致具体技术实施起来没有固定的套路。而由于开发者技术能力的参差不齐,也就使得很多I'M系统在实际的效果上会有较大问题,对于用户而言,也将直接在产品体验上反映出来。通过上一章内容的总结,我们已经对I'M中消息持续一致性问题所产生的缘由有了较为深刻的认识。从纯技术的角度来说,假设只有一个发送方,一个接收方,上下游连接只有一条socket的连接,通过阻塞的方式通讯,这样的情况下,难道不能保证先发出的消息被先处理,进而被先展示给消息的接收者吗?是的,可以,但实际生产情况下,不太可能出现这种I'M系统,毕竟单发送方、单接收方、单socket的连接阻塞方式,这样的I'M一旦做出来,产品经理会立马死给你看。实际上一对一聊天的两个人。
02:50
并不需要全局消息持续的一致,因为聊天只在两人的同一会话在发声,只需要对于同一个发送方A发给B的消息持续一致就行了。常见优化方案在A网B发出的消息中加上发送方案本地的一个绝对时序,比如本机时间出来表示接收方B的展现时序,那么当接收方B收到消息后,即使极端情况下消息可能存在乱序到达,但因为这个乱序的时间差对于普通用户来说体感是很短的。在UI展现层,按照消息中自带的绝对时序排个序后再显示,用户其实是没有太多感知的。假设N个群友在一个I'M群里聊天,应该怎样保证所有群员收到消息的显示时序一致性呢?首先,不能像一对1聊天那样利用发送方的绝对时序来保证消息顺序,因为群聊发送方不单点,时间也不一致,或许我们可以利用服务器的单点做序列化。
03:50
还有没有进一步的优化方法呢?从技术角度看,群消息其实也不用保证全局消息序列有序,而只要保证一个群内的消息有序即可,这样的话,消息ID序列化就成了一个很好的思路。应用系统架构下,消息的绝对时序是很困难的,原因多种多样,比如没有全局时钟,多发送方、多接收方、多线程网络传输不确定性的一对一单聊时,其实只需要保证发出的时序与接收的时序一致,就基本能让用户感觉不到乱序了。多对多的群聊情况下,保证同一群内的所有接收方消息时序一致,也就能让用户感觉不到乱血了。方法有两种,一种单点绝对时序,另一种实现消息ID的序列化,也就是实现一种全局递增消息ID。
我来说两句