Rabbitmq Two Notes

The message go from here

are mandatory and immediate channel. basicPublish method two parameters, which are transmitted during the message when the destination unreachable message is returned to the producer function. 

When the mandatory parameter set to true, the switch could not find a qualifying queue according to their type and routing key, RabbitMQ will call Basic.Return command message is returned to the producer. When mandatory parameter set to false, the above-described situation occurs, the message is discarded directly.

Producers by calling channel. AddReturnListener to add Xin ReturnListener monitor implementation.

When imrnediate parameter set to true, if the switch to route messages to the queue discover that there are no consumers on the queue, so that the message will not be stored in the queue. When all queues and routing key matches are not consumers, the message will pass Basic. Return back to the producers. imrnediate parameters affect the performance of the mirror queue, increasing the complexity of the code, the recommended method of alternative TTL and DLX.

Backup switch, the English name for Altemate Exchange, the producer at the time of sending the message if you do not set mandatory parameters, the message will not be lost in case of routing: If the mandatory parameter settings, you need to add programming logic of ReturnListener, producers code will become complicated. If you do not want to complicate producers of programming logic, do not want to lose the message, you can use the backup switch, so you can not route messages stored in RabbitMQ, and then when needed to process these messages.

By adding in a statement exchanger (call channel.exchangeDeclare method) when alternate-exchange parameters to achieve, can also be achieved through policy (Policy) approach. If both are used, then the former is a higher priority will overwrite Policy settings.

如果备份交换器和 mandatory 参数一起使用,那么 mandatory 参数无效。

过期时间 (TTL)

设置消息的 TTL

两种方法可以设置消息的 TTL, 第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。第二种方法是对消息本身进行单独设置,每条消息的 TTL 可以不同。如 果两种方法一起使用,则消息的 TTL 以两者之间较小的那个数值为准。消息在队列中的生存时间一旦超过设置的 TTL 值时,就会变成"死信" (Dead Message)

1.通过队列属性设置

2.对消息本身进行单独设置

 

第一种一旦消息过期,就会从队列中抹去,第二种,即使消息过期,也不会马上从队列中抹去,因为每条消息是否过期是在即将投递到消费者之前判定的。

为什么这两种方法处理的方式不一样?因为第一种方法里,队列中己过期的消息肯定在队 列头部, RabbitMQ 只要定期从队头开始扫描是否有过期的消息即可。而第二种方法里,每条消息的过期时间不同,如果要删除所有过期消息势必要扫描整个队列,所以不如等到此消息即将 被消费时再判定是否过期, 如果过期再进行删除即可。

设置队列的 TTL

通过 channel . queueDeclare 方法中的 x-expires 参数可以控制队列被自动删除前处 于未使用状态的时间。未使用的意思是队列上没有任何的消费者,队列也没有被重新声明,并
且在过期时间段内也未调用过 Basic . Get 命令。

RabbitMQ 会确保在过期时间到达后将队列删除,但是不保障删除的动作有多及时 。在 RabbitMQ 重启后, 持久化的队列的过期时间会被重新计算。

Map<String, Object> args =new HashMap<String, Object>() ;

args . put( "x-expires" , 1800000);

channel . queueDeclare("myqueue" , false, false, false, args) ;

死信队列( Dead-Letter-Exchange)

当消息在一个队列中变成死信 (dead message) 之后,它能被重新被发送到另一个交换器中,这个交换器就是 DLX,绑定 DLX 的队列就称之为死信队列。

消息变成死信一般是由于以下几种情况:

  1. 消息被拒绝 (Basic.Reject/Basic .Nack),井且设置 requeue 参数为 false;
  2. 消息过期;
  3. 队列达到最大长度。

对于 RabbitMQ 来说, DLX 是一个非常有用的特性。 它可以处理异常情况下,消息不能够被消费者正确消费(消费者调用了 Basic.Nack 或者 Basic.Reject) 而被置入死信队列中
的情况,后续分析程序可以通过消费这个死信队列中的内容来分析当时所遇到的异常情况,进而可以改善和优化系统

延迟队列

一个应用中需要将每条消息都设置为 10 秒的延迟, 生产者通过 exchange.normal 这个交换器将发送的消息存储在 queue.normal 这个队列中。消费者 订阅的并非是 queue.normal 这个队列,而是 queue.dlx 这个队列。当消息从 queue.normal 这个队列中过期之后被存入 queue.dlx 这个队列中,消费者就恰巧消费到了延迟 10 秒的这条消息。

在真实应用中,对于延迟队列可以根据延迟时间的长短分为多个等级,一般分为 5 秒、 10秒、 30 秒、 1 分钟、 5 分钟、 10 分钟、 30 分钟、 1 小时这几个维度.

持久化

RabbitMQ的持久化分为三个部分:交换器的持久化、队列的持久化和消息的持久化。

 交换器和队列的持久化是通过在声明时是将 durable 参数置为 true 实现的,消息的持久化是通过将消息的投递模式 (BasicProperties 中的 deliveryMode 属性)设置为 2 即可实现消息的持久化。

带来的问题:

1.影响性能,建议对可靠性不是很高的消息不持久化

2.设置了持久化,并不能保证数据百分之百不丢失,

  情况一,autoAck为true, 消费者接收消息后宕机了,数据会丢失,那么应该设置autoAck为false,手动确认。

       情况二,持久化消息存入磁盘需要一定的时间,在这段时间内服务器宕机了,数据丢失,那么可以引入 RabbitMQ 的镜像队列机,相当于副本,提高高可用。

生产者确认

两种解决方式:

  • 通过事务机制实现:
  • 通过发送方确认 (publisher confirm) 机制实现。

事务机制

事务确实能够解决消息发送方和 RabbitMQ 之间消息确认的问题,只有消息成功被 RabbitMQ 接收,事务才能提交成功,否则便可在捕获异常之后进行事务回滚,与此同时可以进 行消息重发。但是使用事务机制会"吸干" RabbitMQ 的性能。

发送方确认机制

生产者将信道设置成 confmn (确认)模式,一旦信道进入 confmn 模式,所有在该信道上面发布的消息都会被指派一个唯一的 ID(从 l 开始),一旦消息被投递到所有匹配的队列之后, RabbitMQ 就会发送一个确认 (Basic.Ack) 给生产者(包含消息的唯一 ID),这就使得生产 者知晓消息已经正确到达了目的地了。如果消息和队列是可持久化的,那么确认消息会在消息写入磁盘之后发出。 RabbitMQ 回传给生产者的确认消息中的 deliveryTag 包含了确认消息的序号,此外 RabbitMQ 也可以设置 channel . basicAck 方法中的 multiple 参数,表示到 这个序号之前的所有消息都己经得到了处理。

 

 

Guess you like

Origin www.cnblogs.com/lostyears/p/10927561.html