消息队列常见问题

1、异常处理

1、1 处理机制:死信队列和异常消息队

 

死信队列:由于某种原因无法传递的消息都放置在死信队列上,主要触发点(MCA 如果远程消息不能交付,MCA 发送的消息不能进行数据转换,Trigger Monitor 出发消息失败)。

回退队列:在外部应用在消费队列中消息时,如果发生异常,会发送回滚命令,回滚后的消息始终会放在队列的顶部,不断被处理和回滚,导致队陷入死循环状态,为了解决这个问题,MQ提供一种机制,选中队列右键--》属性--》存储器,设置回退队列和阀值,如设置队列为q1,阀值为2,则在rollback两次后将消息转入q1。

两者都为消息的可靠传输提供一种机制来处理异常。

 

两者的区别:

1. 起作用的阶段,死信队列主要在发送阶段,回退队列主要在消息的消费阶段生成。

2. 死信队列由系统触发, 回退队列主要由应用发送rollback触发。

3. 死信队列一个队列管理器只有一个,而回退队列可以为每个队列设置一个。

 

1.2处理手段:

首先要根据消息的类型,然后再根据是死信和回退队列进行处理。

a) 针对死信队列,需要分析具体原因,重新发起,最后做成自动恢复

b)针对回退队列,如果是能容忍部分丢弃的消息,那么将对应的回退队列的信息持久化即可;如果不能容忍丢失,那么需要人工介入处理。

从最终用户的角度来说,系统应该做到不感知到死信,针对回退的信息,人工介入进行处理,处理的过程中,是否不允许进行同样的业务,需要根据业务的需求来做。

 

1.3典型的案例

更详细见参考文档b

image

 

业务交换机:正常接收发送者,发送过来的消息,交换机类型topic

AE交换机: 当业务交换机无法根据指定的routingkey去路由到队列的时候,会全部发送到AE交换机.发送到此队列的消息属于,业务垃圾消息,或者攻击消息类型,交换机类型fanout

死信交换机:用于处理消费者,消费失败回退的消息,根据死信交换机的routingkey发送到死信队列,交换机类型 topic


EXAMPLE:
业务routingkey: hello/task_queue
生产者发送routingkey: hello task_queue michael
最后业务交换机根据routingkey 会把匹配 hello 和task_queue的发送到业务队列1和业务队列2,michael routingkey没匹配,直接发送到AE交换机,AE交换机的类型为fanout,直接到了告警队列里面,这时候就说明,生产者有问题,或者有一些非法生产者在猜测routingkey,这时候就可以告警处理.
当正常的消息到了业务队列后,消费者监听这个队列进行处理,在消费者处理的过程中,难免会有一些消息处理失败,因为业务的种种原因,但是这些消息一旦失败,那么就会影响性能和后面的消息的消费,这时候就需要一个死信队列,来存放这个消费不了的消息,进入死信队列后,在进行其他处理.


消息消费失败处理方式:
一 进入死信队列(进入死信的三种方式)
1.消息被拒绝(basic.reject or basic.nack)并且requeue=false
2.消息TTL过期
3.队列达到最大长度
二 重新发布此消息到对应的队列(low

 

2、参考文档:

a、http://blog.csdn.net/coderepository/article/details/7023304    死信队列和异常消息队列区别 

b、 http://blog.csdn.net/qq_29778131/article/details/52536965      Rabbitmq消费失败死信队列

c、https://technet.microsoft.com/zh-cn/library/ms789035.aspx/  使用死信队列处理消息传输故障