rabbitMQ 初探-環境搭建、erlang客戶端例子教程

rabbitMQ 初探-環境搭建、erlang客戶端例子教程


1. rabbitMQ簡介

    rabbitmq起源於Advanced Message Queuing Protocol(AMQP,高級消息隊列協議,參見 [AMQP-wiki]),AMQP從一開始就設計成爲開放標準,以解決衆多的消息隊列需求和拓撲結構問題。憑藉開放,任何人均可以執行這一標準,針對標準編碼的任何人均可以和任意AMQP供應商提供的MQ服務器進行交互。AMQP解決分佈式環境下的通訊問題,而Erlang是最適合實現AMQP代理服務器的語言,由於AMQP展示的就是每一部電話交換機的架構,Erlang是Ericson(愛立信)本來爲了電話交換機而開發的編程語言,其分佈式編程和健壯的故障恢復的特點特別適合AMQP。因爲rabbitmq的核心開發人員使用Erlang寫了一個原型測試網絡延遲,發現用Erlang編寫的分佈式計算庫和原生socket擁有同樣的延遲,因而他們決定起名爲Rabbit:兔子行動很是迅速且繁殖瘋狂,特別適合分佈式軟件的命名,也便於記憶。rabbitmq解決了只有少許預算同時也要須要消息通訊的問題,解決了應用集成和高強度事務處理負載的問題。現在,不少技術公司和金融公司都在使用rabbitmq,官方頁面有至關豐富的文檔,github上面也有不少rabbitmq的例子,客戶端有各類版本,好比lisp,.net,elixir,erlang,go,haskell,java,js,objective-c,perl,php,python,ruby,swift等。本文旨在幫助初學者搭建rabbitmq的環境,而後跑一個erlang的客戶端例子,算是入門。(我本身按照網上其餘人的例子還有官網的例子,沒能正常跑起來,即使是對照《RabbitMQ實戰-高效部署分佈式消息隊列》這本書抄的python代碼,都曲折無比,不能正常跑起來。因此將遇到的一些坑記錄下來,但願能減小後來者的時間。)php

    rabbitmq是一個訂閱-發佈的消息隊列,生產者生成數據,發往rabbitmq,消費者根據訂閱,消費生產者的消息。html


2. 環境搭建

    個人rabbitmq是安裝在linux環境下的,erlang客戶端能夠跑在linux下,也能夠跑在windows下。java

  •  第一步是下載安裝rabbitmq,去官網的下載頁面選擇適合本身的版本,我選擇的是rabbitmq-server-generic-unix-3.6.12.tar.xz,而後解壓,
    tar -xvf rabbitmq-server-generic-unix-3.6.12.tar.xz
    解壓以後會產生rabbitmq_server - 3.6.12目錄,rabbitmq-server是免安裝的,解壓以後就立馬能用了,直接運行命令就能跑起來了
    rabbitmq_server-3.6.12/sbin/rabbitmq-server
    若是要後臺啓動,能夠加"-detached"參數
    rabbitmq_server-3.6.12/sbin/rabbitmq-server -detached
    關於rabbitmq的命令,能夠參考這個:RabbitMQ經常使用命令。若是讀者以爲每次都輸入路徑很麻煩,能夠把rabbitmq-server這個可執行文件拷貝到/usr/bin目錄下,這樣直接輸入rabbitmq-server命令就能夠了。啓動rabbitmq-server以後,咱們須要編寫客戶端的例子。因爲我使用的是erlang的例子,因此應該有erlang的運行環境。
  • 第二步是客戶端的環境,包括安裝erlang環境,而且安裝rebar。安裝erlang環境並不在本文的講解之列,讀者能夠參考這篇文章自行安裝:源碼安裝erlang。rebar的安裝能夠參考這篇文章:用 rebar 來構建、編譯、測試、發佈 Erlang 應用程序,其實很簡單,就這麼幾行:
    git clone git://github.com/rebar/rebar.git
    cd rebar
    ./bootstrap

    上面編譯好以後,在當前目錄下就會生成一個名爲"rebar"獨立的erlang腳本(escript),把它放在你想建立標準Erlang/OTP項目的目錄路徑下便可使用,或者把rebar放在/usr/bin目錄下,就像前面的rabbitmq-server同樣,能夠直接在shell裏面運行rebar命令。之因此推薦使用rebar,是由於rabar真的很好用,構建erlang的項目特別方便,還能自動生成gen_server等的代碼模板。我在使用了一次rebar以後,就決定之後全部的erlang項目都使用rebar來構建(說得好像本身能寫多少erlang項目似的( ⊙ o ⊙ )),因此建議沒用過rebar的讀者好好看一下前面的rebar的參考文章。最後推薦一款erlang的編輯器:IntelliJ IDEA,它是java語言開發的集成環境,IntelliJ在業界被公認爲最好的java開發工具之一,可是它對erlang的支持也很是完善,比我以前用來編寫erlang的sublime好用得多。讀者能夠去他的官網下載對應環境的版本,而後參考使用IntelliJ IDEA配置Erlang開發環境配置erlang環境。Intellij IDEA能夠選擇erlang環境,安裝rebar插件,還提供了shell能夠直接運行erl命令,十分方便。若是Intellij IDEA的中文輸入有問題,能夠參考這篇文章:完全解決了Intellij IDEA 2017.2 中文沒法輸入及中英文無法自由切換的問題。若是沒有安裝這個軟件也不要緊,下面的例子都會使用rebar命令來完成編譯。python

3. hello world例子

    環境配置好了以後,咱們就能夠開始編寫hello world的例子了。我這邊的測試環境是在linux上面,rabbitmq的客戶端和服務端都在上面完成(windows下面用Intellij IDEA + rebar能夠搞定客戶端)。前面說過,直接運行 sbin/rabbitmq-server -detached 就將服務端啓動了。接下來的工做都是erlang客戶端的工做。linux

  • 首先新建一個「my_rabbit_test」文件夾,將前面生成的可執行文件rebar拷貝進去。
  • 咱們利用rebar構建項目的骨架,執行命令:
    ./rebar create-app appid=myapp

    就能夠生成src文件夾,src文件夾中的myapp.app.src是OTP應用程序的資源文件,myapp_app.erl是OTP應用程序的Application behaviour,myapp_sup.erl是OTP應用程序的Supervisor behaviour。
    git

  • 接下來繼續執行 ./rebar compile,可以看見生成了ebin目錄,ebin中的myapp.app文件指定了起始模塊是myapp_app。src目錄中的「myapp.app.src」一樣指定了這些。若是咱們進入到 ebin目錄,而後執行erl進入erl的shell界面的話,輸入 application:start(myapp)就能啓動 myapp_app 模塊了。 因此咱們要作的就是往 myapp_sup.erl和myapp_app.erl塞代碼。
  • 咱們在myapp_app.erl中加入一段簡單的測試代碼
  • -module(myapp_app).
    
    -behaviour(application).
    -include_lib("amqp_client/include/amqp_client.hrl").
    
    %% Application callbacks
    -export([start/2, stop/1]).
    -export([test/0]).
    
    %% ===================================================================
    %% Application callbacks
    %% ===================================================================
    
    start(_StartType, _StartArgs) ->
        myapp_sup:start_link().
    
    stop(_State) ->
        ok.
    
    
    test() ->
        %% Start a network connection
        {ok, Connection} =
        amqp_connection:start(
            #amqp_params_network{
                host = "192.168.3.142",
                username = <<"test_user">>,
                password = <<"123456">>,
                virtual_host = <<"mytest">>
            }),
        io:format("connection"),
        %% Open a channel on the connection
        {ok, Channel} = amqp_connection:open_channel(Connection),
        %% Declare a queue
        #'queue.declare_ok'{queue = Q}
        = amqp_channel:call(Channel, #'queue.declare'{}),
        %% Publish a message
        Payload = <<"foobar">>,
        Publish = #'basic.publish'{exchange = <<>>, routing_key = Q},
        amqp_channel:cast(Channel, Publish, #amqp_msg{payload = Payload}),
        %% Get the message back from the queue
        Get = #'basic.get'{queue = Q},
        {#'basic.get_ok'{delivery_tag = Tag}, Content}
        = amqp_channel:call(Channel, Get),
        #amqp_msg{payload = Body} = Content,
        io:format("Body:~p~n",[Body]),
        %% Do something with the message payload
        %% (some work here)
    
        %% Ack the message
        amqp_channel:cast(Channel, #'basic.ack'{delivery_tag = Tag}),
    
        %% Close the channel
        amqp_channel:close(Channel),
        %% Close the connection
        amqp_connection:close(Connection),
    
        ok.

    從代碼中能夠看見用到了amqp_client,因此咱們應該下載rabbitmq的針對erlang的客戶端依賴,下面會講到這個,這裏咱們關注一下amqp_connection:start()這個函數,它的參數是一個結構體,在結構體中的變量中,username,password,virtual_host都是binary格式的,這個要注意,我以前就是寫成字符串格式,沒有轉成二進制格式,老是報錯。另外,因爲代碼中的這些值都是我自定義的,因此首先要在rabbitmq-server上面建立這些用戶和vhost,也就是在個人linux虛擬機192.168.3.142(就是個人rabbitmq-server服務器)上面,執行以下命令:程序員

  • #新增一個vhost
    sbin/rabbitmqctl add_vhost mytest
    #新增一個user
    sbin/rabbitmqctl add_user test_user 123456
    #爲用戶設置vhost上面的權限
    sbin/rabbitmqctl set_permissions -p mytest test_user ".*" ".*" ".*"

  • 因爲代碼中依賴了rabbitmq的客戶端,因此咱們須要下載這個依賴。咱們首先在代碼目錄下新建一個libs目錄,而後將須要下載的兩個依賴amqp_clientrabbit_common下載到該目錄下,而後解壓
  • unzip ./amqp_client-3.6.12.ez 
    unzip ./rabbit_common-3.6.12.ez

    解壓以後就能看見兩個目錄,這兩個目錄中均有ebin目錄,已是編譯好了的代碼,能夠直接利用。在代碼目錄下新建rebar.config文件,在其中加入以下代碼:github

  • {lib_dirs, ["libs"]}.
  • 而後咱們就能夠在代碼目錄下執行 ./rebar compile命令進行編譯了,編譯以後的beam文件在ebin目錄下,進入ebin目錄,執行erl -pa 的命令開始測試
  • ./rebar compile
    cd ebin/
    erl -pa ../libs/amqp_client-3.6.12/ebin/ -pa ../libs/rabbit_common-3.6.12/ebin/

    這裏必定要加上 -pa的選項,選項裏面指定了加載rabbitmq的客戶端的ebin目錄,不然跑不起來。我查了不少資料發現都沒人說這個,也許這對於erlang程序員來講是再正常不過的事情,不過對於我這種新手來講,着實是花了不少時間摸索的。

    能夠看到效果,這個「test」的例子已經成功的跑起來了。若是是windows下面用Intellij IDEA + rebar,編譯以後,用erl命令運行shell的時候也須要加-pa選項,將依賴的ebin目錄加進去。
    另外,還有一種辦法,那就是執行 ./rebar shell 命令也能夠達到 -pa 的效果(同事erlang老司機教的)。
     objective-c

    ./rebar shell

    寫到這裏,一個rabbitmq的erlang客戶端的例子已經寫完了。本文其實花了不少功夫在環境搭建上面,真正的代碼其實很短。若是不想搭建這麼多環境,想快速體驗一下rabbitmq的安裝和例子,能夠參考這篇文章:rabbitmq安裝和運行rabbitmq-tutorials裏的erlang例子。下一篇博客,將會講解rabbitmq的使用,而後介紹利用rebar生成gen_server的模板,生成一個服務,方便調用。知識和文筆有限,不妥之處,還望指出,謝謝。shell

相關文章
相關標籤/搜索