天天看点

【原创】管理 RabbitMQ 服务器的几种方式

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_)&lt;var_name&gt;</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_&lt;var_name&gt; to defaults if not set</code>

<code># 若未手动设置 $rabbitmq_nodename 则设置其为默认值 ${nodename}</code>

<code>[</code><code>"x"</code> <code>=</code><code>"x$rabbitmq_nodename"</code> <code>] &amp;&amp; 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>] &amp;&amp; rabbitmq_ctl_erl_args=${ctl_erl_args}</code>

<code>##--- end of overridden &lt;var_name&gt; 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&gt;</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>&gt;</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>] &amp;&amp; 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 ] &amp;&amp; \</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} ] &amp;&amp; . ${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 中。 

继续阅读