阿里消息中间件ONS消息乱序问题(二)

原创
2018/03/26 14:31
阅读数 648

顺序消息:消息的有序是 消息消费时,能够按照发送的顺序进行消费。

例如:假如生产者产生的两条消息M1 、M2 要保证两条消息的顺序来消费应该怎么做,我们可能想到这样的场景:

M1发送到S1 , M2发送到S2,如果保证M1先于M2被消费,需要M1到达消费端后,通知S2 , 然后S2再将消息M2发送到消费端。

这个模式存在的问题是:如果M1,M2分别发送到两台Server,由于两台Server服务器的网络环境可能不同,所以,不能保证M1先到达, 所以也就不能保证M1先被订阅者消费。那么就要在MQServer集群维护消息的顺序,如何解决:其中一种解决方式是把消息发送到同一台消息服务器上。

这样可以保证M1先于M2到达MQServer(客户端等到M1发送成功后再发送M2),根据先到达先消费的原则,M1会先于M2被消费,能保证顺序。

这个模型,理论上可以保证消息的顺序,但实际运行中你可能会遇到下面问题。

只要将消息从一台服务器发往另一台服务器,就会出现网络延迟问题,如上图所示,如果发送M1耗时大于发送M2耗时,那么M2就先被消费,仍然不能保证消息的顺序,即使M1和M2同事到达消费端,由于不清楚消费端1和消费端2的负载情况,仍然有可能出现M2先于M1被消费。如何解决这个问题? 将M1和M2发往同一个消费者即可。且发送M1后,需要消费端响应成功后才能发送M2。

但是会引入另外一个问题,如果发送M1后,消费端1没响应,那是继续发送M2呢 还是重新发送M1?一般为了保证消息一定被消费,肯定会选择重发M1到另外一个消费端2,如下所示:

这样的模型就能保证严格的消息顺序了,但是消费端1没有响应Server时有两种情况,一种是M1确实没有到达,另外一种情况是消费端1已响应。但是Server没收到。如果是第二种情况,重发M1,就会造成M1被重复消费,也就是我们所说的 消息重复的问题。

严格的顺序消息非常容易理解,而且处理问题也比较容易,要实现严格的顺序消息,简单且可行的方法就是:

保证生产者-MQServer-消费者是一对一的关系

这样设计,并行度就成了消息系统的瓶颈(吞吐量不够),也会导致更多地异常处理,比如:只要消费端出现了问题,就会导致整个处理流程的阻塞,我们不得不花费更多地经理来解决阻塞问题。

但我们的最终目标是要集群的高容错性和高吞吐量。这似乎是一对不可协调的矛盾,那么阿里是如何解决的?

世界上解决一个计算机问题字简单的方法:“恰好”不需要解决它! ——沈询

有些问题看起来重要,但实际上我们可以通过合理的设计或者将问题分解来规避。如果硬要把时间花在解决它们身上,实际上是浪费时间,效率 低下的,从这个角度来看消息的顺序问题,我们可以得出两个结论:

  1. 不关注乱序的应用实际大量存在
  2. 队列无序并不意味着消息无序

 

 

 

 

 

 

 

 

展开阅读全文
ONS
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部