RabbitMQ的構架

山本美月

初識rabbitMQ

RabbitMQ 是一個由 Erlang 語言開發的 AMQP 的開源實現。html

AMQP :Advanced Message Queue,高級消息隊列協議。它是應用層協議的一個開放標準,爲面向消息的中間件設計,基於此協議的客戶端與消息中間件可傳遞消息,並不受產品、開發語言等條件的限制。linux

RabbitMQ 最初起源於金融系統,用於在分佈式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。具體特色包括:緩存

RabbitMQ 特色

  1. 可靠性(Reliability)安全

    RabbitMQ 使用一些機制來保證可靠性,如持久化、傳輸確認、發佈確認。服務器

  2. 靈活的路由(Flexible Routing)多線程

    在消息進入隊列以前,經過 Exchange 來路由消息的。對於典型的路由功能,RabbitMQ 已經提供了一些內置的 Exchange 來實現。針對更復雜的路由功能,能夠將多個 Exchange 綁定在一塊兒,也經過插件機制實現本身的 Exchange 。負載均衡

  3. 消息集羣(Clustering)tcp

    多個 RabbitMQ 服務器能夠組成一個集羣,造成一個邏輯 Broker 。分佈式

  4. 高可用(Highly Available Queues)ide

    隊列能夠在集羣中的機器上進行鏡像,使得在部分節點出問題的狀況下隊列仍然可用。

  5. 多種協議(Multi-protocol)

    RabbitMQ 支持多種消息隊列協議,好比 STOMP、MQTT 等等。

  6. 多語言客戶端(Many Clients)

    RabbitMQ 幾乎支持全部經常使用語言,好比 Java、.NET、Ruby 等等。

  7. 管理界面(Management UI)

    RabbitMQ 提供了一個易用的用戶界面,使得用戶能夠監控和管理消息 Broker 的許多方面。

  8. 跟蹤機制(Tracing)

    若是消息異常,RabbitMQ 提供了消息跟蹤機制,使用者能夠找出發生了什麼。

  9. 插件機制(Plugin System)

    RabbitMQ 提供了許多插件,來從多方面進行擴展,也能夠編寫本身的插件。

Rabbitmq使用流程

rabbitmq做爲消息隊列,一條消息從發佈到訂閱消費的完整流程爲:

消息   -->  交換機exchange  ---> 隊列queue  --->  消費者

rabbitmq的核心就在交換機和隊列

  • 發佈者(推送消息的一端):

    1. 建立一個tcp長鏈接connection,鏈接rabbitmq的監聽端口5672;
    2. 在TCP長鏈接下建立一個信道channel,信道能夠理解爲connection的一個分支;
    3. 經過信道向rabbitmq聲明一個交換機exchange,設置交換機的類型,名稱,是否持久化等屬性;
    4. 經過信道向rabbitmq聲明一個隊列queue,設置隊列的名稱,是否持久化等參數;
    5. 經過信道向rabbitmq聲明一個綁定binding,設置綁定的交換機名稱,隊列名稱,綁定的路由鍵;
    6. 經過信道向rabbitmq推送一條消息,指定交換機和路由;
  • 消費者(接收消息的一端):

    1. 從第一步到第四步和發佈者作的事情是如出一轍的;
    2. 經過信道向rabbitmq聲明一個訂閱,訂閱特定的queue,而且設置回調函數及是否確認等;
    3. 經過信道監聽rabbitmq推送過來的消息;
    4. 消費的時候能夠設置是否自動確認,若是是手動的話須要手動ack來確認消費完成才最終結束消費流程

深刻理解

  • 建立鏈接connection

    • rabbitmq實現的是AMQP通訊協議,其所容許的最大AMQP鏈接數,本質上是TCP鏈接數;
    • 採用TCP長鏈接,自帶SSL認證機制,相似https,保證數據的傳輸安全;
    • 其TCP鏈接的上限能夠經過調整操做系統的限制來變動,詳情linux修改TCP最大鏈接數
  • 建立信道channel

    • 信道channel能夠理解成是connection下的分支,也就是說多個channel共享一個connection,爲何要這麼作呢?
    • 建立TCP鏈接是一個很是耗時的操做,若是一個應用須要多個connection的話,每次的建立和關閉會性能下降,而建立多個channel共享一個connection提升性能,節約系統資源;
    • 多個channel是相互獨立隔離的,這致使了一個問題就是,因爲主機只能識別不一樣的TCP鏈接,但不能識別不一樣的信道發送過來的消息,所以rabbitmq爲每一個建立的信道分配了一個信道ID用來識別不一樣信道發送的消息;
    • 每一個信道都是爲獨立的進程或線程準備的,所以多線程或多進程共享信道是不被容許的;
    • 在一個TCP下可建立的chnnel的數量理論上是沒有上限的,只取決於系統資源,但能夠經過配置channel_max參數設置上限;
  • 聲明交換機exchange

    • 做用:交換機使用來管理分發消息的,一邊接受發佈者提交的消息,根據消息提供的參數選擇相應的處理辦法,交換機是不會存儲消息的,只有轉發或丟棄功能;

    • 若是消息攜帶的路由鍵沒有對應的路由隊列,交換機會將消息丟棄;

    • 重要屬性:名稱,是否持久化;

    • 類型:

      1. 直連交換機direct

        • 顧名思義直連交換機根據消息攜帶的路由鍵將該消息投遞到綁定的隊列;
        • 若是有多個隊列使用相同的路由鍵和直連交換機綁定,那麼直連交換機會將消息同時轉發到多個隊列;
        • rabbitmq自己存在默認交換機,默認交換機的本質就是名稱爲空的直連交換機,當任何一個新的隊列被聲明的時候,rabbitmq會使用這個隊列的名字做爲路由鍵自動綁定默認交換機;
        • 經過rabbitmqctl list_exchanges命令查看全部的交換機,能夠看到有一個名稱爲空的direct;
      2. 扇形交換機funout

        • 做用:扇形交換機會將消息推送到綁定的全部的隊列中,不會理會路由鍵是什麼;
        • 在聲明funout和隊列綁定的時候,也有一個路由鍵參數,可是寫什麼都無所謂,funout會將其忽略的;
      3. 主題交換機topic

        • 做用:主題交換機使用比較複雜的路由鍵匹配規則實現一路或多路路由;
        • 路由鍵規則:
        • 使用.分割的詞語列表,也能夠是單個詞語,長度不能超過255個字節;
        • *號用來匹配一個單詞,這個單詞不能爲空,#號用來匹配0個或多個單詞;
      4. 頭交換機headers

        • 經過判斷消息中攜帶的額外的屬性來分發消息給對應的隊列,性質和直連交換機很類似;
        • 其區別在於使用消息的屬性替換路由鍵做爲路由的規則;

注意

每一個交換機的名字是惟一的,若是重複聲明交換機而且聲明的參數徹底同樣,那麼mq會忽略該聲明;

若是聲明交換機已經存在,但修改了它的屬性,好比類型或持久化等,那麼會報錯;因此修改的方法是先刪除原來的交換機再建立一個新的交換機;

隊列queue

  • queue用來緩存消息,並向消費者推送消息;
  • 聲明隊列的名稱最多255個字節,能夠是任意字符串;
  • 若是聲明時名字爲空,mq會隨機生成一個名字;
  • 聲明隊列不能夠用amq.開頭,不然報錯;
  • 若是多個消費者訂閱同一個隊列的消息,那麼隊列會用輪詢的方式推送消息,這種方式能夠實現負載均衡;

注意:

  • 每一個隊列的名字是惟一的,若是重複聲明交換機而且聲明的參數徹底同樣,那麼mq會忽略該聲明;
  • 若是聲明的該隊列已經存在,但修改了它的屬性,好比類型或持久化等,那麼會報錯;因此修改的方法是先刪除原來的隊列再建立一個新的隊列;

消息訂閱

  • 消費者能夠向隊列訂閱消息,每一個消費者都會被分配一個標誌符;
  • 訂閱時能夠設置消費回執,告訴mq何時能夠將消息刪除了,默認是自動刪除的;
  • 消費者也能夠向mq發送 拒絕消息 ,這時消息會被放回隊列等待投遞到其餘的消費者;
  • 消費者訂閱的時候能夠設置預取計數,當存在多個消費者共同訂閱一個隊列的時候,因爲是輪詢機制,但每一個消費者的消費能力多是不同的,這可能形成有的消費者閒的要死,有的忙的要死,設置預取數量,在沒有收到回執確認前,該隊列推送的消息是有限的,能夠提升總體的吞吐量;

消息,交換機,隊列的持久化

  • 消息持久化是在消息投遞前定義的,設置了持久化後,消息會被保存在磁盤,當被消費後會從磁盤中刪除,可是也不能保證100%持久化成功,由於消息是先放到內存中的,若是此時主機崩潰,仍是會有一部分來不及寫入磁盤;
  • 交換機持久化是在聲明該交換機的時候設置的,當主機崩潰或重啓後,mq一從新上線會自動從新聲明一個和原來徹底同樣的交換機;
  • 隊列持久化是在隊列被聲明的時候設置的,mq從新上線會自動從新聲明一個和原來徹底同樣的queue,可是隊列裏的消息會所有丟失;

參考連接

消息隊列之 RabbitMQ

RabbitMQ進程結構分析與性能調優

https://www.rabbitmq.com/admin-guide.html

原博

RabbitMQ的構架

相關文章
相關標籤/搜索