[toc] # 微服務之間,有哪些溝通模式 (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](https://www.rabbitmq.com/tutorials/tutorial-two-dotnet#message-durability) 故創建 Queue 的時候,要確定設定值 `durable: true` 已開啟,確保 RabbitMQ server 重啟時,queue 不會消滅: ```csharp= 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 伺服器才會將這條訊息的內容寫入到磁碟中。範例如下: ```csharp= 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 ](https://www.rabbitmq.com/tutorials/tutorial-two-dotnet#note-on-message-persistence) 但上述的設置,仍有風險。考慮以下兩個情境,訊息仍有機會遺失: 1. Producer 發佈訊息後,在 RabbitMQ 收到並處理之前,Producer 崩潰。 2. RabbitMQ 收到訊息了,但在將其寫入硬碟(持久化)前崩潰。 也就是,到目前為止我們知道, RabbitMQ 與 producer 互動的行為概觀如下: ![image](https://hackmd.io/_uploads/SkO5OT8bge.png) ### 如何確保 Consumer 有處理到它該處理的 message?