RabbitMQ實戰:擴展介紹與系列總結

本系列是「RabbitMQ實戰:高效部署分佈式消息隊列」書籍的總結筆記。php

本篇是「RabbitMQ實戰」系列的最後一篇,主要介紹RabbitMQ插件,瞭解如何安裝和啓用它,列舉一些經常使用的插件,以及如何自定義。html

在介紹以前,先總結下本系列的主要內容,把它們串起來。java

系列總結

開篇時,這樣定義過RabbitMQ:它是一個開源的消息代理和隊列服務器,能夠經過基本協議在徹底不一樣的應用之間共享數據,能夠將做業排隊以便讓分佈式服務進行處理。ios

這句話有幾個關鍵詞:消息代理、隊列服務器、共享數據、分佈式處理,分別來講明下,以加深理解。git

消息代理:能夠把RabbitMQ當作一個代理服務器,一方面把消息生產者和消費者進行了解耦,更靈活;一方面,消息如何分發不用生產者考慮了,RabbitMQ提供多種分發策略。github

隊列服務器:消息最終是緩存在隊列中的,消費者從指定的隊列中消費消息,因此須要管理隊列和隊列中的消息。算法

共享數據:主要是說消息能夠在不一樣應用間傳輸數據,經過AMQP協議進行規範,達到共享數據的目的。數據庫

分佈式處理:多個消費者能夠訂閱同一個隊列,這樣,多臺機器就能夠同時處理同一批數據,達到分佈式處理的效果。編程

若是理解AMQP基本元素和消息模型,上面的概念會很好理解,有2篇文章重點介紹了這塊。緩存

有些場景,對RabbitMQ可用性要求比較高,不允許有消息的丟失,須要瞭解RabbitMQ的可用性保障和實現。另外, 要可以實時監控RabbitMQ的自己及各個組件的運行狀況,有問題時及時報警,快速進行處理。

若是消息量和併發量比較高,須要根據不一樣的業務場景,在可用性和性能上進行平衡,以知足業務的須要。

有些消息比較敏感,在傳輸的過程當中要進行加密處理,經過ssl協議能夠很好的解決。

最後,RabbitMQ提供了一些列的插件,爲咱們提供了不少有用的功能,好比Web管理界面插件、Shovel跨機房複製插件等,還容許咱們自定義插件,擴展須要的功能。

完整索引

  1. 理解消息通訊
  2. 運行和管理
  3. 消息通訊模型和最佳實踐
  4. 可用性分析和實現
  5. 界面管理和監控
  6. 數據傳輸的安全性介紹
  7. 性能和安全

插件介紹

當須要某些功能而服務器沒有時,能夠經過添加插件的方式來進行加強,能夠從網絡上找,也能夠本身編寫插件。

用插件能夠作什麼

先簡單舉幾個例子,這些能夠經過安裝插件來解決:

  • 支持AMQP之外的協議;
  • 不一樣的認證機制(LDAP、自定義數據庫);
  • 消息複製;
  • 新的交換器和路由算法;
  • 消息日誌和審計;

STOMP是一個簡單的基於文本的協議,用於在應用之間傳輸數據,它能夠與ActiveMQ服務器一塊兒工做,若是你的代碼基於ActiveMQ和STOMP,但想使用RabbitMQ,就可使用STOMP插件進行適配。

假設你的系統中全部的用戶管理均經過LDAP,想在RabbitMQ中使用它進行認證,可使用rabbitmq-auth-backend-ldap插件進行集成。

LDAP是輕量目錄訪問協議,一個爲查詢、瀏覽和搜索而優化的專業分佈式數據庫,它呈樹狀結構組織數據,就好象Linux/Unix系統中的文件目錄同樣。目錄數據庫和關係數據庫不一樣,它有優異的讀性能,但寫性能差,而且沒有事務處理、回滾等複雜功能,不適於存儲修改頻繁的數據。因此目錄天生是用來查詢的,就好象它的名字同樣。

還能夠自定義路由規則的交換器,下面會詳細介紹。

查找和管理插件

能夠查看 官網頁面,查找到維護和實驗階段的插件。

再來看看插件的一些管理命令:

開啓插件,插件開啓後,須要重啓RabbitMQ服務器:

./rabbitmq-plugins enable <plugin-name>
複製代碼

禁用插件,禁用插件後,須要重啓RabbitMQ服務器:

./rabbitmq-plugins disable <plugin-name>
複製代碼

查看啓用的插件:

./rabbitmq-plugins list -e
複製代碼

自定義插件

使用一個具體的例子來介紹自定義插件的開發,有這樣一個場景:使用RabbitMQ爲聊天應用建模,該模型中有一個全局聊天室,全部的用戶都鏈接到這裏,每位用戶擁有本身的隊列,綁定到全局fanout交換器上。

每次發消息到該交換器上時,該消息會羣發給全部綁定的隊列上,但若是有一個新的客戶端鏈接到這個聊天室,只會獲得發送給聊天室的新消息,沒法瞭解在加入以前會話的上下文。

若是能將最近的消息發送給新來的客戶,用戶體驗更更好點,能夠經過自定義交換器實現這個功能。

插件開發環境和說明

RabbitMQ開發者制定了開發環境,即RabbitMQ Public Umbrella,經過把它從代碼庫中籤出,而後把本身的插件添加到項目結構中。

RabbitMQ是用Erlang語言開發的,Erlang源代碼是以模塊的方式組織起來的,模塊內的函數實現了應用程序須要提供的功能,插件只須要一個模塊來包含自定義交互器的實現。

在面向對象編程中,擁有接口的概念,在Erlang中有相同的概念:behavious(行爲)。

Erlang behavior 肯定了模塊須要實現和導出哪些函數,這樣調用該模塊的代碼才知道該如何使用它。

另外一個不一樣的地方在於,Erlang沒有java那樣可見性概念,擁有的就是一個模塊導出列表,若是模塊實現了函數fun一、fun2和fun3,但只導出fun1的話,fun2和fun3將沒法被外界調用。

另外,還有一個函數參數數量的概念,能夠接受名字相同、參數數量不一樣的函數,所以behavious能夠肯定函數fun1/1和fun1/2是兩個不一樣的函數。

通常步驟

首先,確認要擴展的behavios,RabbitMQ暴露了一個交換器behavious,名爲rabbit_exchange_type,它會明確須要實現哪些函數來成爲一個符合要求的交換器。

而後,梳理實現思路:咱們要實現的是一個增強版的fanout類型交換器,緩存最近20條消息,能夠基於RabbitMQ上的fanout交換器進行實現。

  • 須要緩存已路由的消息,每當交換器路由消息的時候,就將該消息存儲到某個數據庫中,該功能可在函數route/2中實現;
  • 當隊列綁定到交換器時,須要把緩存的消息投遞過去,該功能可在函數add_binding/3中實現;
  • 當交換器刪除的時候,須要丟棄緩存的消息,該功能可在函數delete/3中實現;

而後,實現交換器behavious,我沒有看相關實現細節,感興趣的能夠查看實現代碼:傳送門

最後,將交換器註冊到RabbitMQ,RabbitMQ維護了一個註冊表,用這張表來跟蹤全部的交換器類型及其模塊名稱,假設將消息發佈到fanout交換器上,RabbitMQ會進入註冊表,檢查由哪一個模塊來實現fanout交換器,找到後,會繼續調用該模塊的路由函數。

因此,須要找到一個方法將自定義交換器添加到註冊表中,RabbitMQ支持啓動步驟的概念,當服務器啓動時會調用一系列步驟,能夠在模塊中添加一個啓動步驟,RabbitMQ啓動是,會將自定義交換器添加到rabbit_registry註冊表中。

-rabbit_boot_step({rabbit_exchange_type_rh_registry, [{description, "recent history exchange type: registry"}, {mfa, {rabbit_registry, register, [exchange, <<"x-recent-history">>, ?MODULE]}}, //註冊自定義交換器 {requires, rabbit_registry}, {enables, kernel_ready}]}).
複製代碼

以上,自定義交換器就完成了,能夠編寫程序進行驗證。

require_once('../lib/php-amqplib/amqp.inc');
define('HOST', 'localhost');
define('PORT', 5672);
define('USER', 'guest');
define('PASS', 'guest');
define('VHOST', '/');

$exchange = 'rh-exchange';
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$ch = $conn->channel();
$ch->exchange_declare($exchange,
        'x-recent-history', //使用自定義交換器
        false,
        true,
        false);
複製代碼

歡迎掃描下方二維碼,關注個人我的微信公衆號,分享個人工做、學習和生活 ~

情情說
相關文章
相關標籤/搜索