一:先進入rabbitmq的安裝目錄下的bin目錄,執行wget -c http://localhost:15672/cli/rabbitmqadmin;(前提是plugin management已經開啓),而後就會下載rabbitmqadmin腳本文件到bin裏node
二:chmod +x rabbitmqadmin,使得全部用戶均可以執行此python腳本;python
三:可經過./rabbitmqadmin --help查看有哪些命令,注意不能用sh或bash命令,由於它不是shell腳本;正則表達式
補充:Routing key和binding key能夠這麼理解,它們本質上都是由Exchange執行,只不過存在兩個子模塊,一個是經過producer產生key的子模塊,一個是經過key找到queue的子模塊,然而這兩個模塊的調用shell
均經過Exchange,它先將producer信息做爲參數調用第一個子模塊產生key,而後將key做爲參數調用第二個子模塊獲得queue,而後對queue執行publish/push操做;(理解有誤但有參考價值)json
四:用法api
1.查看user:./rabbitmqadmin list users [name] [tags](後面的命令省略寫./rabbitmqadmin但默認都有);(加上name表示只看name列)緩存
2.查看vhosts:list vhosts(這個也同樣能夠選要顯示哪些列,如這裏有name和tracing列)bash
3.list connectionscookie
4.list exchangessession
5.list bindings(可加source destination_type destination properties_key
)
6.list permissions
7.list channels
8.list parameters
9.list queues
10.list policies
11.list nodes(最好加上列不然太長了,如name type mem_used)
12.show overview(太長,可加rabbitmq_version cluster_name node queue_totals.messages object_totals.queues
)
13.delete queue name=hello
(刪除一個queue)
14.delete user name=oth
15.delete exchange name=test
16.delete binding source='kk' destination_type=queue destination=test properties_key=test
17.purge queue name=test
用來清空隊列
18.-f raw_json list users
能夠格式化輸出(其中raw_json可換成pretty_json或long,默認是table的格式化)
19.declare queue name=test durable=true
建立一個queue(此時還沒給它配置binding之類的規則),durable是持久的意思;(建立一個queue後rabbitmq會自動爲其建立一個binding,source是空字符串的那個,而destination和routing_key都是queue名)
20.publish routing_key=test payload="just for test"
發佈一條消息(注意這是在建立的queue是test且是默認配置的狀況下成功,若是有自定義配置則不必定能發佈,這裏用的無名的類型是direct的exchange)
這裏還能夠指定有哪一個exchange來mapping,格式爲加個:exchange=my.fanout
21.get queue=test requeue=true
消費一條消息(requequ=true設置爲可重複消費)
22.declare exchange name=my.fanout type=fanout
建立本身的exchange
23.declare binding source=my.fanout destination=test routing_key=first建立一個binding(binding就能夠理解爲一個註冊表項,只不過這裏不是key-value結構而是多列結構)
補充,默認的Exchange(空字符串的那個)在調用api時是amq.default,amp是Adaptive Message Queue的意思;(15672端口也能夠經過post和get生產和消費消息)
補充:查看binding後有source/destination/routing_key三個屬性;其中routing_key就是生產者或消費者請求時會產生的key,暫且理解由一個子模塊產生,而後source就是exchange,而後exchange根據本身的類型如模糊匹配key找到對應的destination值做爲name的queue;而後對此queue操做;
在exchange的外面還有一層context,好比進行查找exchange和給exchange提供routing_key就是由它完成,暫且叫broker把。。
關於Exchange:
有:fanout/direct/topic/headers四種類型
1.fanout:進行最簡單的廣播,即每一個queue都找一邊看有沒有??(應該是,並且直接忽略routing_key,此時能夠指定destination,若是不指定則將找到的queue都publish此payload,雖然此狀況下忽略routing_key但仍是必須得指定就是這麼規定的)
注意這個廣播也是前提有對應source是fanout的exchange的binding存在,也就是這麼說,publish時指定了exchange則先搜索exchange的表找出此exchange發現是fanout類型,而後此exchange忽略routing_key找binding表裏source是此exchange的,發現有
則獲取其destination,若是是queue則直接操做(有個destination_type),若是是exchange則再次搜索exchange表(有點像責任鏈模式),而後將routing_key做爲參數調用此exchange的某個方法去繼續搜索binding表,直到找出對應的queue並執行publish;
注:我以前的理解有誤,routing_key是producer在publish請求時就會攜帶,還能夠攜帶要由哪一個exchange處理的信息(不然默認攜帶exchange名字是空字符串的那個exchange,type是direct對應匹配);
2.direct:根據整個routing_key進行對應一個queue
3.topic:可使用點分routing_key模糊匹配(通配符有*和#,因爲通配性質故能夠組播,即對某一類匹配的queue進行操做,而fanout是對全部的queue都操做[都是以source對應的前提和沒有指定destination])
topic裏經過.號隔開標識符,標識符不能超過255;而後*匹配 一個 標識符(應該不能爲0個),而#能夠匹配 0個或多個標識符,如*.a只能匹配相似aa.a而不能匹配a.aa.a,可是#.a則能夠匹配.a和a.a和aa.a.a等等;
在建立queue後其routing_key默認就是queue的名字,而其exchange就是系統的第一個無名的exchange是direct類型;
其它:
用戶僅能對其所能訪問的virtual hosts中的資源進行操做。這裏的資源指的是virtual hosts中的exchanges、queues等(這兩個具備name),操做包括對資源進行配置、寫、讀。配置權限可建立、刪除、資源並修改資源的行爲,寫權限可向資源發送消息,讀權限從資源獲取消息。好比:
exchange和queue的declare與delete分別須要exchange和queue上的配置權限
exchange的bind與unbind須要exchange的讀寫權限
queue的bind與unbind須要queue寫權限exchange的讀權限
發消息(publish)需exchange的寫權限
獲取或清除(get、consume、purge)消息需queue的讀權限
對何種資源具備配置、寫、讀的權限經過正則表達式來匹配,具體命令以下:set_permissions [-p <vhostpath>] <user> <conf> <write> <
read
>
其中,<conf> <write> <read>的位置分別用正則表達式來匹配特定的資源,如'^(amq\.gen.*|amq\.default)$'(要有三個,".*"其實就是正則表達式匹配任意字符串的pattern)能夠匹配server生成的和默認的exchange,'^$'不匹配任何資源
須要注意的是RabbitMQ會緩存每一個connection或channel的權限驗證結果、所以權限發生變化後須要重連才能生效。
已知應用場景:(消息中間件的存在容許兩個本來耦合的系統之間的處理不是馬上同步的,好比a調用b接口,b反饋是否執行成功,這就存在一個同步關係,而如今是a定時去取b系統執行後發佈的執行狀態,mes定時取wms的叫料處理狀態[無需等待鎖物料完成後給MES反饋]),在vhost裏是能夠有不少queue的;
WCS和WMS之間的指令下發和執行狀態反饋:
但WMS下發給WCS指令時可由原先的http請求改成WMS將指令下發到A這個queue;WCS則訂閱A這個queue;
WCS將指令執行到可反饋的步驟後將反饋消息下發到B這個queue,WMS則訂閱B這個queue;
兩個系統在訂閱(一條消息只會被一個訂閱者讀取到,這個跟觀察者模式略有不一樣)後獲得消息後對消息進行解析獲得其業務類型(故具體的消息最好由一個包裝類進行業務包裝),而後對真正的消息作業務操做;
n)或者說queue對象已經決定了業務類型,好比A queue就是用於m WMS給 n WCS系統發指令;(若是多個consumer訂閱同一個queue或多個producer對同一個queue發佈消息還得好好理理對應的業務場景)
n)多個producer和一個consumer業務場景:好比以前的MES叫料,多個生產單位(多個producer帳號)可能同時出現叫料,而後這些producer都將叫料任務寫到 JL queue,而由一個WMS系統(consumer)來按本身的處理能力去while consume這個JL queue;
每consume到一個叫料任務WMS系統自行決定要先處理完再再次consume仍是放入線程池裏處理馬上consume下一個;(注意若是須要一直對一個queue獲取消息應該用consume而非get,consume是事先訂閱了這個queue它們直接存在鏈接[有點像已經創建tcp鏈接],而get則相似每次都從新創建tcp鏈接,只不過在rabbitmq裏是叫channel,訂閱後channel已經指向了queue)
n)一個或多個producer對應多個consumer的業務場景:好比多個客戶端下單(多個producer),而後調度系統將下單任務寫到XD queue,而由於是分佈式系統,處理下單任務的系統是部署有多個/多套的,每一個訂單任務處理系統代碼都是同樣的,它們都可以處理訂單;
因而每一個訂單處理系統都訂閱了XD queue,而後消息中間件將訂單任務按照必定規律逐條分別給每一個訂單處理系統處理;(這也是爲何一條消息不會同時發送給多個訂閱者,消費者也要作好生產者重複投遞消息的狀況)
n)若是要實現每一個消費者都能消費同一個消息則要經過爲每一個消費者建立一個queue,而後消息到達後給這些queue都offer便可實現,能夠由topic或者配置source/routing_key均相同但destination爲這些queue;(topic能夠只配置少年binding便可direct則要配置不少)
補充:.erlang.cookie其權限要設置爲700,不然啓動時報錯;(通過屢次測試rabbitmq-server貌似只能root啓動[其它用戶啓動雖然沒報錯可是進程是沒開起來的],而rabbitmqctl也要啓動的用戶來操做,綜合考慮仍是就用root啓動和控制rabbitmq好了),能夠sudo啓動
問題找出來了,是由於啓動rabbitmq須要對/var/lib/rabbitmq有mkdir的權限,能夠在root下用chmod 777 -R /var/lib/rabbitmq(或者acl或者group權限都可,反正是遞歸的rwx權限),而後還有/var/log/rabbitmq的遞歸權限,以後就能夠用其它有這幾個目錄遞歸rwx權限的用戶啓動了;
老版本錯誤總結:安裝rabbitmq時自動安裝到了/usr/lib/rabbitmq裏,而啓動rabbitmq-server須要擁有對rabbitmq的寫權限,故啓動rabbitmq-server的用戶必須擁有對應權限,然而/usr/lib目錄不容許將它的寫權限給其它用戶,於是產生其它用戶沒法啓動的結果
,應該是lib有隱藏權限因此沒法賦予其它用戶某些權限(彷佛又不是用了lsattr沒看到隱藏權限),總結若是要能以其它用戶且非sudo啓動rabbitmq則最好手動安裝到其它目錄;(rabbitmq啓動會作一個mkdir /usr/lib/rabbitmq的操做,於是判斷沒有此權限啓動失敗)
補充:rabbitmq裏4369是服務相關的端口號,它起到一個端口映射的功能(erlang port mapper daemon,相似dns),即全部的請求都是經過此端口進來,而後rabbitmq會判斷其命令類型,如是start,stop,status則會將這個命令轉發到25672端口的子服務上,
而rabbitmq啓動時是會緩存一個cookie,若是客戶端執行如start,stop,status等ctl命令25672端口的子服務會判斷對方的相似sessionid的東西是否和本身緩存的同樣,不同說明不是同一個帳戶在操做,所以經過rabbitmqctl操做是不須要user的;
而因爲不能跨文件系統建立連接,故/root下的.erlang.cookie沒法連接到/home/xxx下,所以root啓動的rabbitmq-server是沒法經過其它帳戶關閉的(可是有個小技巧就是將/root/.erlang.cookie cp到/home/silentdoer目錄下就能夠經過silentdoer來status了而無需sudo
,所以sudo執行的命令的~是/root;(rabbitmq-server還會檢測remote的ip若是不是localhost則不容許某些操做)
15672端口則是能夠經過用戶名密碼的方式管理,可是不包括start/stop之類的控制服務的權限;5672則是amqp端口,即生產者消費者是經過這個端口來實現生產和消費消息的;
sudo 沒法cd到/root,根據這個特性實際上能夠將一些只能root,sudo也不行的東西放到/root裏改個特殊名可以有效防止;