发送顺序消息无法利用集群Fail Over
特性消费,顺序消息的并行度依赖于队列数量,存在队列热点问题,个别队列由于哈希不均导致消息过多,消费速度跟不上,产生消息堆积问题遇到消息失败的消息,无法跳过,当前队列消费暂停。
produce在发送消息的时候,把消息发到同一个队列(queue
)中,消费者注册消息监听器为MessageListenerOrderly
,这样就可以保证消费端只有一个线程去消费消息。
注意:把消息发到同一个队列(queue
),不是同一个topic
,默认情况下一个topic
包括4个queue
可以通过实现发送消息的队列选择器方法,实现部分顺序消息。
举例:比如一个数据库通过MQ来同步,只需要保证每个表的数据是同步的就可以。解析binlog
,将表名作为队列选择器的参数,这样就可以保证每个表的数据到同一个队列里面,从而保证表数据的顺序消费。
Topic
,消息子类型用tags来标识,tags可以由应用自由设置。只有发送消息设置了tags,消费方在订阅消息时,才可以利用tags
在broker
做消息过滤。keys
字段,方便将来定位消息丢失问题。服务器会为每个消息创建索引(哈希索引),应用可以通过 topic
,key来查询这条消息内容,以及消息被谁消费。由于是哈希索引,请务必保证key
尽可能唯一,这样可以避免潜在的哈希冲突。
//订单Id
String orderId= "20034568923546";
message.setKeys(orderId);
send result
和key
字段。send
send
消息方法,只要不抛异常,就代表发送成功。但是发送成功会有多个状态,在sendResult
里定义。
SEND_OK
:消息发送成功
FLUSH_DISK_TIMEOUT
:消息发送成功,但是服务器刷盘超时,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢失
FLUSH_SLAVE_TIMEOUT
:消息发送成功,但是服务器同步到Slave时超时,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢失
SLAVE_NOT_AVAILABLE
:消息发送成功,但是此时slave不可用,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢失At Least Once
,所以consumer
可能多次收到同一个消息,此时务必做好幂等。分布式开放消息系统(RocketMQ)的原理与实践 http://www.jianshu.com/p/453c6e7ff81c RocketMQ事务消费和顺序消费详解 http://www.cnblogs.com/520playboy/p/6750023.html