【消息中间件】RabbitMQ如何保证消息的可靠传输

一、消息持久化

   在消息发布前,通过把它的投递模式(delivery mode)选项设置为2来把消息标记为持久化。

   1.1 消息持久化过程:

           当发布一条持久化消息到持久化交换器上时(带有durable=true的exchange),Rabbit会在消息提交到日志文件后
   才发送响应。如果这条消息路由到了非持久化队列,它会自动从持久化日志中移除,并且无法从服务器重启中恢复。
   如果从持久化队列中消费了一条持久化消息的话(并且确认了它),RabbitMQ会在持久化日志中把这条消息标记
   为等待垃圾收集。如果在消费持久化消息前,RabbitMQ重启的话,服务器会自动重建交换器和队列以及绑定,重新
   把持久化日志文件中的消息投递到合适的队列或者交换器上。

   由于消息发布操作不返回任何信息给生产者,那怎么知道服务器是否已经持久化到磁盘呢?服务器可能会把消息在写入磁盘
   前就宕机了,消息可能因此而丢失。那如何确保消息持久化到磁盘了呢?

 1.2 消息持久化方式

   1.2.1、开启事务模式(transaction)

              当继续处理其它消息前,必须确保代理接收到了消息(并且已经将消息路由到所有匹配的队列),我们需要将这些
      行为包装到一个事务当中。在AMQP中,在把信道设置成事务模式后,通过发送多个AMQP命令确保消息路由到所有
      匹配的队列时,只有所有的命令都执行成功,事务才可以提交。开启事务,意味着生产者的消息之间产生同步,这会使
      Rabbit的性能大大降低。


   1.2.2、发送方确认模式。

            将信道设置成confirm模式,而且只有重新创建信道才能关闭该设置。一旦信道进入confirm模式,所有在
     信道上发布的消息都会被分配一个唯一的ID号(从1开始)。一旦消息被投递给所有匹配的队列后,信道会
     发送一个确认给生产者(包含消息的唯一ID)。这使得生产者知晓消息已经安全到达目的队列了。如果消息和
     队列是可持久化的,那么确认消息只会在队列将消息写入磁盘后才会发出。发送方确认模式最大的好处是它们
     是异步的。一旦发布了一条消息,生产者就可以在等待确认的同时继续发送下一条。当确认消息最终收到的时候,
     生产者应用的回调方法就会触发来处理该确认消息。如果Rabbit发生了内部错误从而导致了消息的丢失,Rabbit
     会发送一条nack(未确认)消息,来告诉生产者该消息已丢失。由于没有消息回滚的概念(相对于事务),因此
     发送方确认模式更加轻量级。

二、发送到持久化的交换器。

   设置交换器(exchange)的durable属性设置为true。


三、路由到持久化队列

   设置队列(Queue)的durable属性设置为true。

你可能感兴趣的:(中间件)