一般mq能够保证先到队列的消息按照顺序分发给消费者消费来保证顺序,可是一个队列有多个消费者消费的时候,那将失去这个保证,由于这些消息被多个线程并发的消费。可是有的时候消息按照顺序处理是很重要的,那咱们该如何来保证消息的顺序呢,下面将从activemq和rocketmq来看看,它们是如何来保证消息的顺序问题的?咱们还能够有别的处理方案么?网络
Activemq处理方案session
一、利用Activemq的高级特性:consumer之独有消费者(exclusive consumer)并发
在ActiveMQ4.x中能够采用Exclusive Consumer,broker会从queue中,一次发送消息给一个消费者,这样就避免了多个消费者并发消费的问题,从而保证顺序,配置以下:负载均衡
queue = new ActiveMQQueue("TEST.QUEUE?consumer.exclusive=true"); consumer = session.createConsumer(queue);
图1
独占消息就是在有多个消费者同时消费一个queue时,能够保证只有一个消费者能够消费消息,这样虽然保证了消息的顺序问题,不过也带来了一个问题,就是这个queue的全部消息将只会在这一个主消费者上消费,其余消费者将闲置,达不到负载均衡分配,而实际业务咱们可能更多的是这样的场景,好比一个订单会发出一组顺序消息,咱们只要求这一组消息是顺序消费的,而订单与订单之间又是能够并行消费的,不须要顺序,由于顺序也没有任何意义,有没有办法作到呢?答案是能够的,下面就来看看activemq的另外一个高级特性之messageGroup。分布式
二、利用Activemq的高级特性:messageGroupsspa
Message Groups特性是一种负载均衡的机制。在一个消息被分发到consumer以前,broker首先检查消息JMSXGroupID属性。若是存在,那么broker会检查是否有某个consumer拥有这个message group。若是没有,那么broker会选择一个consumer,并将它关联到这个message group。此后,这个consumer会接收这个message group的全部消息,直到:线程
图2
配置以下:code
bytesMessage.setStringProperty("JMSXGroupID", "constact-20100000002"); bytesMessage.setIntProperty("JMSXGroupSeq", -1);
如上图所示,同一个queue中,拥有相同JMSXGroupID的消息将发往同一个消费者,解决顺序问题,不一样分组的消息又能被其余消费者并行消费,解决负载均衡的问题,一箭双鵰啦!server
Rocketmq处理方案blog
那rocketmq又是如何保证消息顺序消费的问题呢?
Rocketmq跟传统的MQ有一点区别,这里有必要讲一下topic的概念,Topic是RocketMQ中的一个重要概念,RocketMQ的各组件都是围绕着Topic创建起对应关系的,在RocketMQ官方文档和本文中, Topic在不一样的语境下被赋予了两种不一样的语义:
1)消息的Topic属性值:在描述Consumer的订阅设置信息或消息的属性时。
2)Topic属性为某个值的消息(单个消息或消息集合):在描述Broker,Producer和Consumer的对应关系,Queue以及负载均衡策略时。
topic和queue的对应关系是一个topic拥有多个queue,当producer往broken发送消息时,消息会存储在topic下的不一样队列中,而一个队列只会被一个consumer消费,这样消息户被均衡负载到不一样的队列下,也就是会被多个消费者并行消费,顺序就没法保证了。该怎么办呢?答案是把须要顺序消费的消息发送到同一台broker server下的同一个队列,而这些消息也只会被同一个消费者消费,这样就能够保证严格的顺序了,以下图:
一、消息要有顺序,首先得保证producer发送消息有顺序,如上图msg1,msg2,msg3发送到queue0是要有顺序的,只要producer等待前面的消息发送成功,在发送后面的消息就彻底能够保证了,
二、假设msg1发送给consumer1,消费没有响应,该怎么办呢?是继续发送msg2仍是从新发送msg1,通常为了保证消息必定被消费,确定会选择重发msg1到下一台消费者consumer2。
三、消费端1没有响应Server时有两种状况,一种是msg1确实没有到达(数据在网络传送中丢失),另一种消费端已经消费msg2且已经发送响应消息,只是MQ Server端没有收到。若是是第二种状况,重发msg1,就会形成msg1被重复消费。也就引入了消息重复问题,那就要幂等了。
Rocketmq一样作到了保证消息的顺序状况下,均衡消费的消费消息。
综上,我看到,在分布式系统中,要想消息有顺序的被消费,不管是Activemq仍是Rocketmq都要想办法让有顺序的消息被同一消费者消费,而不是并发的消费,在消费者消费成功后,接着才会消费下一个消息,这样就能够保证了严格的顺序。