MQ如何解决消息的顺序问题和消息的重复问题

做者:CHEN川微信

连接:http://www.jianshu.com/p/453c6e7ff81c网络

來源:简书分布式

著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。ide

1、摘要

分布式消息系统做为实现分布式系统可扩展、可伸缩性的关键组件,须要具备高吞吐量、高可用等特色。而谈到消息系统的设计,就回避不了两个问题:spa

一、消息的顺序问题设计

二、消息的重复问题3d

2、关键特性以及其实现原理

2.一、顺序消息日志

要实现严格的顺序消息,简单且可行的办法就是:htm

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

这样的设计虽然简单易行,但也会存在一些很严重的问题,好比:

一、并行度就会成为消息系统的瓶颈(吞吐量不够)

二、更多的异常处理,好比:只要消费端出现问题,就会致使整个处理流程阻塞,咱们不得不花费更多的精力来解决阻塞的问题。

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

有些问题,看起来很重要,但实际上咱们能够经过合理的设计或者将问题分解来规避。若是硬要把时间花在解决问题自己,实际上不只效率低下,并且也是一种浪费。从这个角度来看消息的顺序问题,咱们能够得出两个结论:

一、不关注乱序的应用实际大量存在

二、队列无序并不意味着消息无序

2.二、消息重复

上面在解决消息顺序问题时,引入了一个新的问题,就是消息重复。那么MQ是怎样解决消息重复的问题呢?仍是“刚好”不解决。

形成消息的重复的根本缘由是:网络不可达。只要经过网络交换数据,就没法避免这个问题。因此解决这个问题的办法就是不解决,转而绕过这个问题。那么问题就变成了:若是消费端收到两条同样的消息,应该怎样处理?

一、消费端处理消息的业务逻辑保持幂等性

二、保证每条消息都有惟一编号且保证消息处理成功与去重表的日志同时出现

第1条很好理解,只要保持幂等性,无论来多少条重复消息,最后处理的结果都同样。第2条原理就是利用一张日志表来记录已经处理成功的消息的ID,若是新到的消息ID已经在日志表中,那么就再也不处理这条消息。

咱们能够看到第1条的解决方式,很明显应该在消费端实现,不属于消息系统要实现的功能。第2条能够消息系统实现,也能够业务端实现。正常状况下出现重复消息的几率不必定大,且由消息系统实现的话,确定会对消息系统的吞吐量和高可用有影响,因此最好仍是由业务端本身处理消息重复的问题,这也是MQ不解决消息重复的问题的缘由。

MQ不保证消息不重复,若是你的业务须要保证严格的不重复消息,须要你本身在业务端去重。

3、阅读原文

源代码在线演示和解读

做者:阿笨 

      官方QQ群:422315558 跟着阿笨一块儿玩NET 574187616跟着阿笨一块儿玩NET(二) 

      我的讲师课堂主页:http://study.163.com/provider/2544628/index.htm 

      我的微信公众号课程主页:http://dwz.cn/ABenNET