天天看點

RabbitMQ設計了解-使用模式(場景)

簡介:

基于隊列消費的模式,Rabbit提供了集中使用的場景模式。

1 直推模式

直推模式中消息隻做簡單的發送和接

RabbitMQ設計了解-使用模式(場景)

2 多工作者模式

多工作者模式中,推送任務消息之後,由于有的任務是耗時的任務,當耗時任務的時候,很長時間才會傳回确認消息或者是斷開了連接配接等情況很容易導緻隊列的阻塞。如果處理端能有多個,那麼可以極大的提高效率和容錯。

RabbitMQ設計了解-使用模式(場景)

3 釋出訂閱模式(Exchange)

釋出訂閱模式中,消息的釋出者與消息的接受者不再直接操作于隊列,而是通過将exchange與隊列關聯起來。消息的發送與接收都與exchange關聯起來,不再受隊列的限制。在釋出訂閱模式中,隊列不再限制,一個用戶端可以将任意隊列與exchange綁定(某種程度上也可以避免死隊列)。

在訂閱模式中廣播的方式有三種:

1 全局廣播(exchange=finout)

對于所有訂閱了的終端全局都發送釋出的消息,全局的消息。

RabbitMQ設計了解-使用模式(場景)

2 局域廣播(exchange=direct)

在全局廣播的基礎上,有些廣播希望隻被部分訂閱方看到,此時有個routing_key實作該功能。routing_key起到的作用其實可以看做是分組,将聲明了相同routing_key的用戶端配置設定在一個組,并且接收"routing_key"組的消息。

RabbitMQ設計了解-使用模式(場景)

3 混合廣播(exchange=topics)

混合廣播的方式是将上面兩種方式的優點結合起來,既支援全局廣播,也支援局域廣播,在聲明exchange的時候需要聲明"topics",并且使用适配符(通配符+ '.'):

  • * (star) can substitute for exactly one word.(*字元代表一個字元)
  •  # (hash) can substitute for zero or more words.(#代表0或者多個字元)

例如:*.orange.* , lazy.#

來實作用戶端既可以接收全局的廣播也可以接收

RabbitMQ設計了解-使用模式(場景)

二、Rabbit 中需要注意的一些機制

1 确認機制

隊列的确認機制我覺得很有必要講清楚,确認機制應該是和我們的實際使用場景息息相關,下面就我對官網閱讀之後的一些了解:

RabbitMQ在預設的情況下,是會自動實作:釋出方發送消息給隊列,隊列分發給用戶端,用戶端在接受到消息,并且處理完之後發送一個ACK(确認)。

       在正常情況下,是比較好的機制。但是當我們希望任務不能被丢失,也就是說任務一定會被執行,在特殊情況下可能不能滿足(隊列連接配接斷開,TCP斷開連接配接,http層斷開連接配接等)。當特殊情況發生的時候,Worker1隊列斷開連接配接,我們沒有辦法确認是在什麼環節出現的問題。這個時候如果嘗試關閉自動确認機制,那麼隻要沒有收到消息的确認ACK,隊列就會給另外正常的隊列Worker2(如果沒有正常的隊列會在下次綁定該隊列的時候下發消息)發送消息并讓Worker2去完成任務。這樣就達到了任務消息不會丢失。

RabbitMQ設計了解-使用模式(場景)

當關閉了自動确認機制之後,隊列就會儲存任務消息,每當有用戶端連接配接到隊列或者已經有綁定隊列的Worker,就會下發任務消息到該Worker,直到某個隊列通過tag(Long)回複一個ack為止。這種機制能很大程度的保證消息不會丢失

2 隊列存儲(持久性)

基于确認機制保證了消息不會丢失,但是當服務端挂掉或者意外停機時,所有隊列都會隊列中的消息也會丢失,是以為了解決這種情況RabbitMQ提供了持久化隊列的方式:

RabbitMQ設計了解-使用模式(場景)

隊列聲明持久化(發送方和接收方都需要持久化聲明)之後,發送的消息也需要聲明持久化

RabbitMQ設計了解-使用模式(場景)

持久化需要注意的點:

上面的持久化并不是意味着完全精準的實作了消息不會丢失。盡管RabbitMQ會儲存消息到硬碟,但是在接收到消息到儲存到硬碟之間還是有一個很短的時間窗。RabbitMQ不會為每一個消息做fsync,可能是先儲存在緩存,然後再儲存在硬碟上。是以RabbitMQ的持久化并不是很完善,但是相比簡單的任務隊列來說已經足夠了。如果希望一個更加完善的持久化方案參考:(https://www.rabbitmq.com/confirms.html)

RabbitMQ設計了解-使用模式(場景)

3 單隊列多Worker對等機制

       在上面說到的多工作者模式當中,我們應該注意的是,預設情況下RabbitMQ會平均的為每一個Worker配置設定對等的任務,也就是說隊列消費是平均的,不會出現某個Worker一直空閑,某個Worker一直繁忙的情況。但是,針對于一些比較特殊的任務來說,比如耗時的任務,這個時候如果還是平均配置設定的話就會出現某個Worker任務阻塞,因為耗時任務還未完成就又推送新的任務的情況。這個時候RabbitMQ提供的解決方案是(QOS):

RabbitMQ設計了解-使用模式(場景)