Try   HackMD

微服務之間,有哪些溝通模式 (Communication Patterns)?

RabbitMQ 如何幫我們做到 job queue and Pub/Sub patterns?

Job Queue 如何實現?

Pub/Sub 如何實現?

如何避免訊息遺失?

Producer 端如何確保 RabbitMQ 確實地收下 message?

首先,在關心 message 之前,queues 本身也會因為 RabbitMQ 重啟而銷毀:

When RabbitMQ quits or crashes it will forget the queues and messages unless you tell it not to. Message durability | RabbitMQ

故創建 Queue 的時候,要確定設定值 durable: true 已開啟,確保 RabbitMQ server 重啟時,queue 不會消滅:

await channel.QueueDeclareAsync( queue: queue_name, durable: true, // enable this exclusive: false, autoDelete: false, arguments: null);

接著關心 messages 如何不遺失。RabbitMQ server 預設行為是:無論該 Queue 是持久化 (durable = true) 的還是非持久化 (durable = false) 的,這條訊息的內容只儲存在記憶體中。

故得在發佈的參數裡,明確設置 Persistent = true。此時,如果該 Queue 是持久化 (durable = true) 的,RabbitMQ 伺服器才會將這條訊息的內容寫入到磁碟中。範例如下:

var properties = new BasicProperties { Persistent = true // enable this }; await channel.BasicPublishAsync( exchange: string.Empty, routingKey: queue_name, mandatory: true, basicProperties: properties, body: body);

Note on Message Persistence | RabbitMQ

但上述的設置,仍有風險。考慮以下兩個情境,訊息仍有機會遺失:

  1. Producer 發佈訊息後,在 RabbitMQ 收到並處理之前,Producer 崩潰。
  2. RabbitMQ 收到訊息了,但在將其寫入硬碟(持久化)前崩潰。

也就是,到目前為止我們知道, RabbitMQ 與 producer 互動的行為概觀如下:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

如何確保 Consumer 有處理到它該處理的 message?