1.通過 rabbitmqctl 腳本
rabbitmqctl 是 shell 腳本,其通過 exec 調用了 erl 程式。會間接調用到如下兩個 shell 腳本:
rabbitmq-env
rabbitmq-defaults
在使用該腳本時允許使用者定制的環境變量為:
rabbitmq_nodename 預設值 ${nodename}
rabbitmq_ctl_erl_args 預設值 ${ctl_erl_args}
下面分别看下這幾個腳本都幹了哪些事情。
【rabbitmqctl】
<a href="http://my.oschina.net/moooofly/blog/170965#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<code>[root@betty chapter-9]</code><code># vi /usr/sbin/rabbitmqctl</code>
<code>#!/bin/sh</code>
<code>## the contents of this file are subject to the mozilla public license</code>
<code>## version 1.1 (the "license"); you may not use this file except in</code>
<code>## compliance with the license. you may obtain a copy of the license</code>
<code>## at http://www.mozilla.org/mpl/</code>
<code>##</code>
<code>## software distributed under the license is distributed on an "as is"</code>
<code>## basis, without warranty of any kind, either express or implied. see</code>
<code>## the license for the specific language governing rights and</code>
<code>## limitations under the license.</code>
<code>## the original code is rabbitmq.</code>
<code>## the initial developer of the original code is vmware, inc.</code>
<code>## copyright (c) 2007-2013 vmware, inc. all rights reserved.</code>
<code># get default settings with user overrides for (rabbitmq_)<var_name></code>
<code># non-empty defaults should be set in rabbitmq-env</code>
<code>. `</code><code>dirname</code> <code>$0`</code><code>/rabbitmq-env</code> <code># $0 為 /usr/sbin/rabbitmqctl 是以 `dirname $0`/rabbitmq-env</code>
<code> </code><code># 為 /usr/sbin/rabbitmq-env</code>
<code> </code><code># 這裡是初始化了一些預設的環境變量值(詳見下面)</code>
<code>##--- set environment vars rabbitmq_<var_name> to defaults if not set</code>
<code># 若未手動設定 $rabbitmq_nodename 則設定其為預設值 ${nodename}</code>
<code>[</code><code>"x"</code> <code>=</code><code>"x$rabbitmq_nodename"</code> <code>] && rabbitmq_nodename=${nodename}</code>
<code># 若未手動設定 $rabbitmq_ctl_erl_args 則設定其值為預設值 ${ctl_erl_args}</code>
<code>[</code><code>"x"</code> <code>=</code><code>"x$rabbitmq_ctl_erl_args"</code> <code>] && rabbitmq_ctl_erl_args=${ctl_erl_args}</code>
<code>##--- end of overridden <var_name> variables</code>
<code>exec</code> <code>${erl_dir}erl \</code>
<code> </code><code>-pa</code><code>"${rabbitmq_home}/ebin"</code> <code>\</code>
<code> </code><code>-noinput \</code>
<code> </code><code>-hidden \</code>
<code> </code><code>${rabbitmq_ctl_erl_args} \</code>
<code> </code><code>-sname rabbitmqctl$$ \ </code><code># $$ 為目前程序的 pid</code>
<code> </code><code>-boot</code><code>"${clean_boot_file}"</code> <code>\</code>
<code> </code><code>-s rabbit_control_main \</code>
<code> </code><code>-nodename $rabbitmq_nodename \</code>
<code> </code><code>-extra</code><code>"$@"</code>
【rabbitmq-env】
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<code>[root@betty ~]</code><code># vi /usr/sbin/rabbitmq-env</code>
<code># determine where this script is really located (if this script is</code>
<code># invoked from another script, this is the location of the caller)</code>
<code>script_path=</code><code>"$0"</code> <code># $0 的值應該為 /usr/sbin/rabbitmq-env</code>
<code>while</code> <code>[ -h</code><code>"$script_path"</code> <code>] ;</code><code>do</code> <code># -h 用于判定是否為符号連結</code>
<code> </code><code># readlink -f 擷取符号連結 rabbitmq-env 所對應的完整路徑 /usr/lib/rabbitmq/sbin/rabbitmq-env</code>
<code> </code><code>full_path=`readlink -f $script_path 2></code><code>/dev/null</code><code>`</code>
<code> </code><code>if</code> <code>[</code><code>"$?"</code> <code>!=</code><code>"0"</code> <code>];</code><code>then</code> <code># 判定上一步執行結果是否為成功</code>
<code> </code><code># 直接執行 readlink 将擷取符号連結 rabbitmq-env 所對應的相對路徑 ../lib/rabbitmq/sbin/rabbitmq-env</code>
<code> </code><code>rel_path=`readlink $script_path`</code>
<code> </code><code># expr string : regexp 判定 $rel_path 是不是以 '/' 開頭</code>
<code> </code><code>if</code> <code>expr</code> <code>"$rel_path"</code> <code>:</code><code>'/.*'</code> <code>></code><code>/dev/null</code><code>;</code><code>then</code>
<code> </code><code>script_path=</code><code>"$rel_path"</code> <code># 以 '/' 開頭</code>
<code> </code><code>else</code>
<code> </code><code>script_path=</code><code>"`dirname "</code><code>$script_path</code><code>"`/$rel_path"</code>
<code> </code><code>fi</code>
<code> </code><code>else</code>
<code> </code><code>script_path=$full_path</code>
<code> </code><code>fi</code>
<code>done</code>
<code>script_dir=`</code><code>dirname</code> <code>$script_path` </code><code># 得到 script_dir = /usr/lib/rabbitmq/sbin</code>
<code>rabbitmq_home=</code><code>"${script_dir}/.."</code> <code># 得到 rabbitmq_home = /usr/lib/rabbitmq/</code>
<code>[</code><code>"x"</code> <code>=</code><code>"x$hostname"</code> <code>] && hostname=`</code><code>env</code> <code>hostname</code><code>` </code><code># 得到 hostname = betty</code>
<code>nodename=rabbit@${hostname%%.*} </code><code># 得到 nodename = rabbit@betty 其中 ${hostname%%.*} 的含義是</code>
<code> </code><code># 以 '.' 為分隔位置,從後開始作最長比對的删除</code>
<code> </code><code># 如果是一個 '%' 則為最短比對</code>
<code>## set defaults</code>
<code>. ${script_dir}</code><code>/rabbitmq-defaults</code> <code># 初始化預設環境變量(詳見下面)</code>
<code>## common defaults</code>
<code>server_erl_args="+k</code><code>true</code> <code>+a30 +p 1048576 \</code>
<code> </code><code>-kernel inet_default_connect_options [{nodelay,</code><code>true</code><code>}]" </code><code># 預設的通用配置選項</code>
<code># warn about old rabbitmq.conf file, if no new one</code>
<code>if</code> <code>[ -f</code><code>/etc/rabbitmq/rabbitmq</code><code>.conf ] && \</code>
<code> </code><code>[ ! -f ${conf_env_file} ] ;</code><code>then</code>
<code> </code><code>echo</code> <code>-n</code><code>"warning: ignoring /etc/rabbitmq/rabbitmq.conf -- "</code> <code># echo -n 不輸出換行符</code>
<code> </code><code>echo</code> <code>"location has moved to ${conf_env_file}"</code>
<code>fi</code>
<code>## get configuration variables from the configure environment file</code>
<code>[ -f ${conf_env_file} ] && . ${conf_env_file}</code><code># 如果存在 ${conf_env_file} 檔案則執行該 環境配置 檔案</code>
【 rabbitmq-defaults 】
<code>[root@betty ~]</code><code># vi /usr/sbin/rabbitmq-defaults</code>
<code>## copyright (c) 2012-2013 vmware, inc. all rights reserved.</code>
<code>### next line potentially updated in package install steps</code>
<code>sys_prefix=</code>
<code>### next line will be updated when generating a standalone release</code>
<code>erl_dir=</code>
<code>clean_boot_file=start_clean</code>
<code>sasl_boot_file=start_sasl</code>
<code>## set default values</code>
<code>config_file=${sys_prefix}</code><code>/etc/rabbitmq/rabbitmq</code> <code># 配置檔案路徑</code>
<code>log_base=${sys_prefix}</code><code>/var/log/rabbitmq</code> <code># 日志檔案路徑</code>
<code>mnesia_base=${sys_prefix}</code><code>/var/lib/rabbitmq/mnesia</code> <code># 資料庫路徑</code>
<code>enabled_plugins_file=${sys_prefix}</code><code>/etc/rabbitmq/enabled_plugins</code> <code># 記錄已使能插件的檔案</code>
<code>plugins_dir=</code><code>"${rabbitmq_home}/plugins"</code> <code># 插件所在路徑</code>
<code>conf_env_file=${sys_prefix}</code><code>/etc/rabbitmq/rabbitmq-env</code><code>.conf </code><code># 環境配置檔案</code>
2. 通過 rabbitmq management plugin
首先想到的問題是:為什麼有了 rabbitmqctl 還要 rabbitmq management plugin ?
原因一,若想通過 rabbitmqctl 來對 rabbitmq server 進行操作,要求必須要有 erlang 運作環境、必須擁有和目标 rabbitmq server 使用的相同 erlang cookie 檔案。
原因二,一旦滿足了上述條件,那麼該通路者将擁有對目前 rabbitmq server 為所欲為的能力,非常危險。
原因三,不是所有人都喜歡敲、以及會敲 cli 指令。
原因四,難于與其他程式設計語言或工具進行內建。
rabbitmq management plugin 提供了如下幾種入口:
web interface -- 通過滑鼠點選就可以檢視各種資訊
rest interface -- 通過 http uri 實作對各種功能的通路
cli interface -- 通過 rabbitmqadmin 腳本通路 (python2.x)
與《rabbitmq in action》中的說明進行對照:
management: web ui
management: http api
management: command line tool
其中,
web ui 提供了在 rabbitmq server 上的可視化操作;
rest api 提供了一種與其他語言和工具內建的方式。傳回的結構均以 json 格式提供,故需要支援 json 解析;需要支援 http basic authentication ;需要手動構造完整的 http request 。支援對傳回結果的排序、顯示過濾,以及擷取曆史資料。(參考 http://youripaddir:15672/api/)
cli interface 優于 rest-based api 的地方是不需要建構 request 中的全部内容,提供了優雅的格式化的輸出。rabbitmqadmin 已經實作了對 rest api 的封裝,提供了更加簡潔的調用接口,能夠對 rabbitmq server 進行管理和監控。
官網原文如下介紹該工具:rabbitmqadmin 提供了 web ui 上所具有的全部功能,且更易于在腳本中使用。rabbitmqadmin 是一個特化的 http 用戶端,但如果你打算在自己的應用程式中調用 rabbitmqadmin ,那麼還是建議你采用直接通路 http api 的方式 。 另外, rabb itmqadmin 一般會在增加可執行權限後放到 /usr/local/bin 中。