隨筆 - 41  文章 - 7  trackbacks - 0
          <2016年7月>
          262728293012
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          在本章節中,我們將展現一些RabbitMQ中的可用插件.然后,我們將展示如何使用現實世界中的例子來開發新插件.
          1. 啟用和配置STOMP插件
          2. 管理RabbitMQ集群
          3. 監控Shovel狀態
          4. 開發新插件– 使用ODBC連接關系數據庫
          介紹
          多虧了插件設施,使得RabbitMQ成為了一個可擴展平臺.它提供了許多通用插件,其中一些已經在前面的章節中解釋過了.
          例如, Federation和Shovel 插件已經在第7章節開發高可用應用程序中詳細講解過了.
          在下面的食譜中,我們將展示其它的可用插件,以及如何開發新插件來擴展RabbitMQ的功能.

          啟用和配置STOMP插件 
          從本書的一開始,我們就已經看過了如何使用插件。管理插件本身實際上也是一個插件。然而,我們的意圖是顯示插件的進一步使用。
          在這個食譜中,我們將看到如何使STOMP插件,以及RabbitMQ提供的進一步可能性。
          通過簡單的(或流)文本定向通訊協議(STOMP)(http://stomp.github.io/),RabbitMQ增加語言的互操作性。
          當安裝了插件后,RabbitMQ的broker不僅可以與AMQP協議操作,也可以與STOMP協議互操作。
          準備
          對于本食譜,你只需要最新版本的RabbitMQ.
          如何做
          為了運行本食譜,你需要執行下面的步驟:
          1. 從 root (Linux)或RabbitMQ命令提示窗口(Windows), 使用下面的檢查當前插件的狀態:
          rabbitmq-plugins list
          2. 然后使用下面的命令來啟用STOMP插件:
          rabbitmq-plugins enable rabbitmq_stomp
          3. 使用下面的命令來重啟RabbitMQ:
          service rabbitmq-server restart
          此時,你可以嘗試使用 Netcat來提交STOMP消息,nc命令( http://en.wikipedia.org/wiki/Netcat ),來自于終端會話(Windows用戶可使用telnet ):
          4. 在shell提示中,輸入下面的nc命令:
          nc localhost 61613
          CONNECT
          ^@
          SEND
          Destination:/queue/test
          This the 1st stomp message
          ^@
          TIP
          注意 ^@ 代表的是CTRL + @的組合, 相當于用一個ASCII碼等于零的性質。
          5. 打開第二個終端,輸入下面的nc命令:
          nc localhost 61613
          CONNECT
          ^@
          SUBSCRIBE
          destination:/queue/test
          ^@
          如何工作
          要列出可用插(步驟1),我們將得到下面的屏幕輸出:

          上圖顯示的是所有可用的插件,其中方括號中為空的表示還未安裝. 標記為[E]的插件是明確安裝的. 標記為[e]的插件是隱式安裝的,也就是說,這些插件是作為其它的插件的依賴而進行安裝的.
          在安裝了STOMP插件之后,我們必須重啟broker以讓修改生效.
          一旦插件激活了,你可以使用簡單的文本STOMP協議來向隊列test發送消息(步驟4). 這樣你將看到下面的截圖:

          在另一個終端,我們可以啟動隊列test來消費消息(步驟5). 這樣你將看到下面的截圖:

          請注意,從消息到最后的文本沒有被類型化,這是實際接收到的消息。
          更多
          在這個食譜中,我們使用了標準的STOMP配置。然而,也可以通過RabbitMQ配置文件的選項來定制其端口,SSL使用.
          你可在http://www.rabbitmq.com/stomp.html查找到更多詳細信息.

          TIP
          注意STOMP完全不同于Web-Stomp, Web-Stomp是封裝在WebSockets中的STOMP.參考第5章節在web應用程序中使用STOMP來開發web監控程序食譜的內容.這兩種協議不具有互操作性。
          此外,也可以使用STOMP來發送其它類型的消息。如使用臨時隊列來發送RPC消息,向交換器發送消息,或從交換器中接收消息.

          也可參考
          在本食譜中,我們已經展示了如何使用Netcat作為文本客戶端來讓RabbitMQ與STOMP插件交互. 但,這不是一種典型在客戶端使用STOMP的方式.
          這里有許多可用的STOMP客戶端APIs.
          你可在http://stomp.github.io/implementations.html中找到可用客戶端包的列表.

          管理RabbitMQ集群
          當部署了一個大的RabbitMQ集群時,管理插件會對集群操作造成一定的開銷.在本食譜中,我們將展示如何減輕這種開銷。
          準備
          為了驗證這個食譜,你需要一個具有至少兩個節點的RabbitMQ集群。如果他們已經安裝了管理插件,你需要刪除它。

          如何做
          1. 使用下面的命令在一個節點上安裝管理插件:
          rabbitmq-plugins enable rabbitmq_management
          2.使用以下命令
          在所有其他節點上安裝管理代理插件:
          rabbitmq-plugins enable rabbitmq_management_agent

          如何工作
          執行這些步驟后,您只能從第一個節點監視整個群集。其他節點將通過代理來更新第一個節點的控制臺狀態,但您無法訪問他們的端口15672。
          通常,你會在幾個節點安裝完整的管理插件,如前端或管理節點和管理代理插件的其它節點。

          監控Shovel狀態
          在第7章節,開發高可用應用程序中,我們已經看過了如何使用Shovel插件.在本食譜中,我們將展示如何使用一個適當的插件來監控其正確行為. 這是rabbitmq_management插件的擴展.

          準備
          要測試這個食譜,我們需要運行兩個RabbitMQ brokers. 在本食譜中,我們將其稱為rabbit@node01和rabbit@node02.
          如何做
          我們假設這兩個broker已經在他們各自的節點上運行了.我們將使用配置文件來配置節點node01上的broker,你也可以從Chapter07/Recipe05中拷貝配置文件:
          1. 在RabbitMQ配置文件中,一般是/etc/rabbit/rabbitmq.config,插入下面的Shovel配置:
          [{rabbitmq_shovel,
          [ {shovels, [ {my_books_shovel,
          [
          {sources, [ {broker, "amqp://node02"}]}
          , {destinations, [ {broker, "amqp://"}]}

          , {queue, <<"myBooksQueueCopy">>}
          , {prefetch_count, 10}
          , {reconnect_delay, 5}
          ]}]}].
          2. 輸入下面的命令來激活插件:
          rabbitmq-plugins enable rabbitmq_management
          rabbitmq-plugins enable rabbitmq_shovel
          rabbitmq-plugins enable rabbitmq_shovel_management
          3. 為修改的broker重啟broker以使配置生效,命令如下:
          service rabbitmq-server restart
          4. 使用下面的地址來訪問RabbitMQ 管理界面:
          http://node01:15672/
          5. 從管理界面中,分別在節點node01和node02上創建myBooksQueueCopy隊列.
          6. 在管理界面,導航至Admin Shovel Status.

          如何工作
          當我們激活Shovel插件時,可通過rabbitmq_shovel_management 插件來監控其行為. 一旦我們激活了插件,由于重定向隊列不存在,你會看到錯誤信息。顯示如下:

          只要我們創建了隊列(步驟5),頁面將在5秒內自動刷新:

          在這個頁面上, RabbitMQ 允許我們監視所有已配置的Shovels.

          開發新插件 – 使用ODBC來操作關系型數據庫

          在前面的食譜中,我們已經看過了,如何使用一些現有的插件。現在,我們將了解如何來開發自定義新插件.
          注意,這不是一種典型實踐. 大部分的操作通常可通過 RabbitMQ/AMQP client API來執行.
          然而,在某些必要的情況下,也需要執行一些定制化的操作.
          這是出于優化目的,或需要嚴格監控broker自己的行為.
          在本食譜中,我們將展示如何讓RabbitMQ來消費消息,并使用ODBC驅動將其存入關系型數據庫中.
          準備
          在這個食譜中,我們需要RabbitMQ 和PostgreSQL. 然而, 由于ODBC驅動的普及,本食譜可以很容易地適應到幾乎所有關系數據庫上。
          另外,我們還需要安裝Mercurial (http://mercurial.selenic.com/),它是RabbitMQ的版本系統,用來檢出RabbitMQ的源代碼. 
          雖然這里的環境是Linux,但只需要稍為修改,本食譜也能工作在Windows上.
          如何做
          現在,我們將安裝和配置PostgreSQL.
          1. 安裝PostgreSQL和它的ODBC驅動. 例如,在基于yum的Linux發行版上(如RedHat, CentOS, Fedor或其它),用roo執行下面的命令.
          yum install postgresql-server
          yum install postgresql-odbc
          postgresql-setup initdb
          service postgresql start
          2. 從RabbitMQ插件中,使用下面的命令來創建一個新用戶(密碼為rmq_plugin_password) 和一個新數據庫:
          su postgres createuser --no-superuser --no-createdb --no-createrole --pwpromptrmq_plugin_user
          createdb --owner rmq_plugin_userrmqdb
          3. ,通過在文件/var/lib/pgsql/data/pg_hba.conf末尾追加下面的行,以允許新創建的用戶訪問給定數據庫(只允許從本地訪問):
          # TYPE DATABASE USER ADDRESS METHOD
          local rmqdb rmq_plugin_user md5
          host rmqdb rmq_plugin_user 127.0.0.1/32 md5
          4.以root身份重新加載PostgreSQL配置:
          service postgresql reload
          5. 此時,你應該可以從本地連接PostgreSQL了,例如,通過執行下面的命令:
          psql --username=rmq_plugin_user --dbname=rmqdb

          6. 完成ODBC驅動的配置來訪問數據庫,要做到這一點,必須在文件/etc/odbc.ini中插入下面的行:
          [rmqDSN]
          Driver = PostgreSQL
          Description = PostgreSQL data source for RabbitMQ
          Servername = localhost
          Port = 5432
          Protocol = 8.4
          Database = rmqdb
          7.現在我們可以使用isql命令來測試ODBC連接,同時我們也可以直接使用Erlang來測試. erl命令如下:
          odbc:start()
          odbc:connect("DSN=rmqDSN;UID=rmq_plugin_user;PWD=rmq_plugin_password", [])
          到目前為止,我們已經準備好了開發插件所需要的東西.現在我們來了解如何啟用metronome 插件.它存在于官方RabbitMQ文檔(http://www.rabbitmq.com/plugin-development.html:
          8. 使用下面的命令來檢出RabbitMQ開發源代碼樹:
          cd $HOME
          hg clone http://hg.rabbitmq.com/rabbitmq-public-umbrella
          cd rabbitmq-public-umbrella
          make co
          9. 使用下面的命令來編譯metronome插件:
          cd rabbitmq-metronome
          make
          10. 在開發的broker中安裝插件及其依賴.
          cd ../rabbitmq-server
          mkdir plugins
          cd plugins
          ln –s ../../rabbitmq-metronome
          ln–s../../rabbitmq-erlang-client
          11.為了避免覆蓋產品環境安裝,即使是我們不用root用戶,我們也需要停止產品服務器,設置一些環境變量,并創建一些相應的目錄以讓RabbitMQ以標準用戶啟動:
          export RABBITMQ_LOG_BASE=$HOME/rmq/log
          export RABBITMQ_MNESIA_BASE=$HOME/rmq/mnesia

          export RABBITMQ_ENABLED_PLUGINS_FILE=$HOME/rmq/enabled_plugins
          mkdir –p $RABBITMQ_LOG_BASE $RABBITMQ_MNESIA_BASE
          12. 現在我們可以啟用開發插件了.
          cd $HOME/rabbitmq-public-umbrella/rabbitmq-server
          scripts/rabbitmq-plugins list
          scripts/rabbitmq-plugins enable rabbitmq_metronome
          13. 最后,啟動開發服務器:
          scripts/rabbitmq-server
          14. 此刻,我們已經準備好了如何開發一個新插件, 它使得通過ODBC的方式,將RabbitMQ與第三方數據庫連接到了一起.你可在Chapter09/Recipe04中找到本食譜的源碼. 你可從Chapter09/Recipe04/
          rabbitmq-odbctap目錄拷貝源碼進RabbitMQ開發樹-rabbitmq-publicumbrella(在步驟8中檢出來的). 通過這種方式,你可以獲得類似于下面截圖的源碼樹:

          15. 要開始開發一個新插件,需要從現有插件rabbitmq-metronome 或 rabbitmq-shovel中拷貝和重命名文件. The makefile will be left unmodified.
          16. 修改
          package.mk文件以反映所需的依賴與測試模塊.
          17. 編輯rabbitmq_odbctap.app.src. 此文件包含Erlang項目所需的資源,在我們的例子中,一般和慣例都必須包含下面的配置:
          {application, rabbitmq_odbctap,
          [{description, "Embedded Rabbit ODBC tap"},
          {vsn, "0.0.0"},
          {modules, []},
          {registered, []},
          {mod, {rabbit_odbctap, []}},
          {env, [{dsn,"DSN"},
          {user,"guest"},
          {password, "guest"},
          {queue, "tapped_queue"}
          ]},
          {applications, [kernel, stdlib, rabbit, amqp_client]}]}.
          18. 定制rabbit_odbctap.erl, 模塊的入口點,為了讓它啟動或停止,需要配置插件自身.
          19. 定制rabbit_odbctap_sup.erl
          對于Erlang管理源節點,通過定義回調來定義主管行為的回調.
          20. 在rabbit_odbctap_worker.erl中實現插件邏輯.這是實際模塊的入口點,在我們這里,它會連接RabbitMQ broker,綁定隊列,并通過ODBC來消費指定數據庫包含的消息.
          21.多個模塊共用的數據定義(也就是Erlang記錄)可放置在include目錄中.如,在rabbit_odbctap.hrl中,你可以找到Erlang記錄odbctap_config的定義,此定義是被rabbit_odbctap.erl、 rabbit_odbctap_worker.erl所共用的.
          22. 準備一個或多個測試模塊.在我們的例子中,在rabbit_odbctap_tests.erl中只能找到一個骨架.
          23. 編譯插件并執行自動化測試.
          cd $HOME/rabbitmq-public-umbrella/rabbimq-odbctap
          make
          make test
          24. 在開發服務器中安裝插件.
          cd ../rabbitmq-server/plugins
          ln –s ../../rabbitmq-odbctap .

          25. 在設置步驟11中所示的環境后,我們可以啟用插件和(重新)啟動服務器了.
          cd $HOME/rabbitmq-public-umbrella/rabbitmq-server
          scripts/rabbitmq-plugins enable rabbitmq_odbctap
          scripts/rabbitmq-server

          如何工作
          為了實戰本食譜,我們一開始就配置了一個PostgreSQL數據庫,以及它相應的ODBC驅動.這部分內容已經在食譜的前半部分中展示過了.
          然后,我們展示了如何啟用樣例模板插件rabbitmq_metronome(RabbitMQ自身在開發樹中提供的).如果一切正常, 步驟13啟動的開發broker將以會以我們標準用戶運行,并在日志文件$HOME/rmq/log/rabbit@localhost.log中,你可能會看到下面的行:
          =INFO REPORT==== 21-Oct-2013::03:28:50 ===
          Server startup complete; 2 plugins started.
          * amqp_client
          * rabbitmq_metronome
          這是開發新插件的起點,即使用Erlang ODBC client來監控已配置PostgreSQL數據庫中的某些給定隊列.這部分內容將在食譜的第三部分展示。
          要實現我們的插件,我們選擇遵循一種公共的方案,即使用模塊來實現Erlang行為.實際上, Erlang 鼓勵使用通過supervisor來解藕應用程序(這里是我們新開發的插件)和運行者(即RabbitMQ自身) 的松耦合架構。
          關于這方面的內容,可參考http://www.erlang.org/doc/man/supervisor.html and http://www.erlang.org/doc/design_principles/sup_princ.html.
          supervisor唯一需要定制的是,可從startup模塊中獲取配置信息,并將其傳遞給worker模塊. 為了達到目的,startup 模塊(rabbit_odbctap.erl)包含了讀取配置信息的代碼。
          read_config() ->
          {ok, Dsn} = application:get_env(dsn),
          {ok, User} = application:get_env(user),
          {ok, Password} = application:get_env(password),
          {ok, Queue} = application:get_env(queue),
          Config = #odbctap_config{
          dsn = Dsn,
          user = User,

          password = Password,
          queue = Queue},
          Config.

          調用application:get_env/1可讓模塊自動訪問如下設置的定義:
          1.在Erlang資源文件rabbitmq_odbctap.app.src中,在編譯時,設置了env鍵:
          ...
          {env, [{dsn,"DSN"},
          {user,"guest"},
          {password, "guest"},
          {queue, "tapped_queue"}
          ]},
          ...
          rabbitmq.config文件中是以運行時讀取的,其配置遵循典型的RabbitMQ (即Erlang)格式 , 且在下面的代碼中指定了rabbitmq_odbctap鍵:
          [{rabbitmq_odbctap,
          [{dsn, "rmqDSN"},
          {user,"rmq_plugin_user"},
          {password, "rmq_plugin_password"},
          {queue, "tapped_queue"}]}].
          在本書的歸檔目錄中,你能找到完整的文件.
          rabbit_odbctap_worker.erl worker 模塊實現gen_server行為.
          你可在http://www.erlang.org/doc/design_principles/gen_server_concepts.html找到更多詳細信息.
          在我們的模塊中,一旦模塊啟動了就會調用 init/2,然后它會通過ODBC客戶端
           Erlang API http://www.erlang.org/
          doc/apps/odbc/來連接ODBC連接器,并觸發RabbitMQ消費者. 重要的一點是,在這種情況下,內嵌RabbitMQ client是連接到本地broker的,即嵌入到同一個Erlang虛擬機中,并會執行下面的調用:
          {ok, Connection} = amqp_connection:start(#amqp_params_direct{})
          通過這種方式,插件可使用內部Erlang連接和更為高效的消息協議, 因為完全避免了AMQP通信協議的編組.

          TIP
          為了能在RabbitMQ日志文件中記錄一些信息,你可以使用與rabbit_log:info/2相似的調用,正如init/2中定義的一樣.
          通過使用gen_server行為, broker 的消息不是從接收塊中消費的(http://www.rabbitmq.com/erlang-client-user-guide.html, 參考訂閱隊列章節), 而是通過handle_info/2回調實施的:
          handle_info({#'basic.deliver'{delivery_tag = Tag},
          #amqp_msg{payload = Payload}},State = #state{channel=Channel,odbcHandle = Ohandle}) ->
          Query = "INSERT INTO rmqmessages VALUES ('now','"++binary_to_list(Payload) ++"')",
          {updated, _} = odbc:sql_query(Ohandle, Query),
          amqp_channel:cast(Channel, #'basic.ack'{delivery_tag = Tag}),
          {noreply, State};
          這是本食譜的核心.當RabbitMQ自身初始化的時候,且數據庫處于打開狀態時,每個消費消息都將得到存儲。

          更多
          非常重要的一點是開發插件是最后的選擇,最好是通過使用AMQP client library來開發一個外部應用程序.
          TIP
          一個插件可能連累RabbitMQ的穩定性.
          因此,只有當極端的整合或對性能有需要時,才可以評估是否開發一個插件。
          posted on 2016-07-20 11:30 胡小軍 閱讀(2595) 評論(1)  編輯  收藏 所屬分類: RabbitMQ

          FeedBack:
          # re: RabbitMQ-CookBook-第9章-擴展RabbitMQ功能 2016-07-21 16:59 貝蒂斯橄欖油報價
          謝謝分享,有用得著的地方,非常感謝  回復  更多評論
            
          主站蜘蛛池模板: 长宁区| 柘荣县| 若羌县| 姜堰市| 衡山县| 曲周县| 梁河县| 铜陵市| 晋城| 鸡西市| 柘城县| 迁西县| 阳城县| 峡江县| 中江县| 香格里拉县| 南川市| 合川市| 高州市| 许昌县| 新干县| 收藏| 亚东县| 泌阳县| 肇州县| 张掖市| 宝鸡市| 淮滨县| 仙居县| 容城县| 太谷县| 惠州市| 普兰店市| 浦东新区| 阿拉善左旗| 高陵县| 绍兴市| 常德市| 稻城县| 舒兰市| 仙游县|