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 中。