RabbitMQ之监控(1)

RabbitMQ作为一个工业级的消息中间件,肯定是缺少不了监控的,RabbitMQ提供了WEB版的页面监控(访问地址:http://xxx.xxx.xxx.xxx:15672/,默认端口号是15672。原文:The web UI is located at: http://server-name:15672/),类似于如下:

当然,需要有相关功能的前提是开启了:rabbitmqctl rabbitmq_management.
如果小用用的话,这个web管理界面就够了,如果公司有专门的团队,比如中间件团队来专门负责一些基础组件,那么必然会有自身的一套生态环境,那么自然而然的独立的且可以和公司其他系统接入的监控系统必不可少,没有监控的代码那是一抹黑的。



要构建独立的监控系统,可以利用RabbitMQ提供的restful http api接口(原文:The HTTP API and its documentation are both located at: http://server-name:15672/api/ (or view our latest HTTP API documentation here).)。当然这个接口的作用远不至于调取一些监控数据,也可以通过api来操作RabbitMQ进行添加删除的操作(GET,PUT,DELETE,POST)。

引用RabbitMQ官网的例子,比如列出所有的vhosts:

再比如创建一个新的vhost:

采用RabbitMQ提供的restful http api来做监控其实很简单,只需调用(比如HttpClient工具):http://server-ip:15672/api/nodes即可。下面展示下博主这里的某些监控指标:broker节点的内存占用,磁盘剩余空间,Socket句柄,Broker子进程数,文件句柄数。监控示例图分别如下:

通过http://server-ip:15672/api/nodes获取到的数据如下:

[
    {
        "cluster_links": [
            {
                "peer_addr": "10.198.197.73",
                "peer_port": 25672,
                "sock_addr": "10.198.198.10",
                "sock_port": 29226,
                "stats": {
                    "send_bytes": 49847976,
                    "send_bytes_details": {
                        "rate": 0
                    },
                    "recv_bytes": 2714074,
                    "recv_bytes_details": {
                        "rate": 0
                    }
                },
                "name": "rabbit@zhuzhonghua2-fqawb"
            }
        ],
        "disk_free": 36541222912,
        "disk_free_details": {
            "rate": 0
        },
        "fd_used": 28,
        "fd_used_details": {
            "rate": 0
        },
        "io_read_avg_time": 0,
        "io_read_avg_time_details": {
            "rate": 0
        },
        "io_read_bytes": 3784705,
        "io_read_bytes_details": {
            "rate": 0
        },
        "io_read_count": 3,
        "io_read_count_details": {
            "rate": 0
        },
        "io_seek_avg_time": 0.054,
        "io_seek_avg_time_details": {
            "rate": 0
        },
        "io_seek_count": 4,
        "io_seek_count_details": {
            "rate": 0
        },
        "io_sync_avg_time": 0,
        "io_sync_avg_time_details": {
            "rate": 0
        },
        "io_sync_count": 2,
        "io_sync_count_details": {
            "rate": 0
        },
        "io_write_avg_time": 0,
        "io_write_avg_time_details": {
            "rate": 0
        },
        "io_write_bytes": 524,
        "io_write_bytes_details": {
            "rate": 0
        },
        "io_write_count": 2,
        "io_write_count_details": {
            "rate": 0
        },
        "mem_used": 53393008,
        "mem_used_details": {
            "rate": 0
        },
        "mnesia_disk_tx_count": 2,
        "mnesia_disk_tx_count_details": {
            "rate": 0
        },
        "mnesia_ram_tx_count": 34,
        "mnesia_ram_tx_count_details": {
            "rate": 0
        },
        "proc_used": 181,
        "proc_used_details": {
            "rate": 0
        },
        "queue_index_journal_write_count": 1,
        "queue_index_journal_write_count_details": {
            "rate": 0
        },
        "queue_index_read_count": 1,
        "queue_index_read_count_details": {
            "rate": 0
        },
        "queue_index_write_count": 1,
        "queue_index_write_count_details": {
            "rate": 0
        },
        "sockets_used": 1,
        "sockets_used_details": {
            "rate": 0
        },
        "partitions": [],
        "os_pid": "795",
        "fd_total": 1024,
        "sockets_total": 829,
        "mem_limit": 3301929779,
        "mem_alarm": false,
        "disk_free_limit": 50000000,
        "disk_free_alarm": false,
        "proc_total": 1048576,
        "rates_mode": "basic",
        "uptime": 100629724,
        "run_queue": 0,
        "processors": 4,
        "exchange_types": [
            {
                "name": "headers",
                "description": "AMQP headers exchange, as per the AMQP specification",
                "enabled": true
            },
            {
                "name": "topic",
                "description": "AMQP topic exchange, as per the AMQP specification",
                "enabled": true
            },
            {
                "name": "direct",
                "description": "AMQP direct exchange, as per the AMQP specification",
                "enabled": true
            },
            {
                "name": "fanout",
                "description": "AMQP fanout exchange, as per the AMQP specification",
                "enabled": true
            }
        ],
        "auth_mechanisms": [
            {
                "name": "PLAIN",
                "description": "SASL PLAIN authentication mechanism",
                "enabled": true
            },
            {
                "name": "AMQPLAIN",
                "description": "QPid AMQPLAIN mechanism",
                "enabled": true
            },
            {
                "name": "RABBIT-CR-DEMO",
                "description": "RabbitMQ Demo challenge-response authentication mechanism",
                "enabled": false
            }
        ],
        "applications": [
            {
                "name": "amqp_client",
                "description": "RabbitMQ AMQP Client",
                "version": "3.5.7"
            },
            {
                "name": "inets",
                "description": "INETS  CXC 138 49",
                "version": "6.3.3"
            },
            {
                "name": "kernel",
                "description": "ERTS  CXC 138 10",
                "version": "5.1"
            },
            {
                "name": "mnesia",
                "description": "MNESIA  CXC 138 12",
                "version": "4.14.1"
            },
            {
                "name": "mochiweb",
                "description": "MochiMedia Web Server",
                "version": "2.7.0-rmq3.5.7-git680dba8"
            },
            {
                "name": "os_mon",
                "description": "CPO  CXC 138 46",
                "version": "2.4.1"
            },
            {
                "name": "rabbit",
                "description": "RabbitMQ",
                "version": "3.5.7"
            },
            {
                "name": "rabbitmq_management",
                "description": "RabbitMQ Management Console",
                "version": "3.5.7"
            },
            {
                "name": "rabbitmq_management_agent",
                "description": "RabbitMQ Management Agent",
                "version": "3.5.7"
            },
            {
                "name": "rabbitmq_web_dispatch",
                "description": "RabbitMQ Web Dispatcher",
                "version": "3.5.7"
            },
            {
                "name": "sasl",
                "description": "SASL  CXC 138 11",
                "version": "3.0.1"
            },
            {
                "name": "stdlib",
                "description": "ERTS  CXC 138 10",
                "version": "3.1"
            },
            {
                "name": "webmachine",
                "description": "webmachine",
                "version": "1.10.3-rmq3.5.7-gite9359c7"
            },
            {
                "name": "xmerl",
                "description": "XML parser",
                "version": "1.3.12"
            }
        ],
        "contexts": [
            {
                "description": "RabbitMQ Management",
                "path": "/",
                "port": "15672"
            }
        ],
        "log_file": "/opt/rabbitmq/sbin/../var/log/rabbitmq/rabbit@hiddenzhu-8drdc.log",
        "sasl_log_file": "/opt/rabbitmq/sbin/../var/log/rabbitmq/rabbit@hiddenzhu-8drdc-sasl.log",
        "db_dir": "/opt/rabbitmq/sbin/../var/lib/rabbitmq/mnesia/rabbit@hiddenzhu-8drdc",
        "config_files": [
            "/opt/rabbitmq/sbin/../etc/rabbitmq/rabbitmq.config (not found)"
        ],
        "net_ticktime": 60,
        "enabled_plugins": [
            "rabbitmq_management"
        ],
        "name": "rabbit@hiddenzhu-8drdc",
        "type": "disc",
        "running": true
    },
    {
        "cluster_links": [
            {
                "peer_addr": "10.198.198.10",
                "peer_port": 29226,
                "sock_addr": "10.198.197.73",
                "sock_port": 25672,
                "stats": {
                    "send_bytes": 2714033,
                    "send_bytes_details": {
                        "rate": 8.2
                    },
                    "recv_bytes": 49847976,
                    "recv_bytes_details": {
                        "rate": 491.6
                    }
                },
                "name": "rabbit@hiddenzhu-8drdc"
            }
        ],
        "disk_free": 34482147328,
        "disk_free_details": {
            "rate": -2457.6
        },
        "fd_used": 36,
        "fd_used_details": {
            "rate": 0.4
        },
        "io_read_avg_time": 0,
        "io_read_avg_time_details": {
            "rate": 0
        },
        "io_read_bytes": 479585,
        "io_read_bytes_details": {
            "rate": 0
        },
        "io_read_count": 6,
        "io_read_count_details": {
            "rate": 0
        },
        "io_seek_count": 1,
        "io_seek_count_details": {
            "rate": 0
        },
        "io_sync_avg_time": 0,
        "io_sync_avg_time_details": {
            "rate": 0
        },
        "io_write_avg_time": 0,
        "io_write_avg_time_details": {
            "rate": 0
        },
        "mem_used": 44401848,
        "mem_used_details": {
            "rate": 7947.2
        },
        "mnesia_disk_tx_count": 6,
        "mnesia_disk_tx_count_details": {
            "rate": 0
        },
        "mnesia_ram_tx_count": 44,
        "mnesia_ram_tx_count_details": {
            "rate": 0
        },
        "proc_used": 194,
        "proc_used_details": {
            "rate": 0
        },
        "queue_index_read_count": 1,
        "queue_index_read_count_details": {
            "rate": 0
        },
        "sockets_used": 1,
        "sockets_used_details": {
            "rate": 0
        },
        "partitions": [],
        "os_pid": "3806",
        "fd_total": 1024,
        "sockets_total": 829,
        "mem_limit": 3301929779,
        "mem_alarm": false,
        "disk_free_limit": 50000000,
        "disk_free_alarm": false,
        "proc_total": 1048576,
        "rates_mode": "basic",
        "uptime": 100632422,
        "run_queue": 0,
        "processors": 4,
        "exchange_types": [
            {
                "name": "headers",
                "description": "AMQP headers exchange, as per the AMQP specification",
                "enabled": true
            },
            {
                "name": "topic",
                "description": "AMQP topic exchange, as per the AMQP specification",
                "enabled": true
            },
            {
                "name": "direct",
                "description": "AMQP direct exchange, as per the AMQP specification",
                "enabled": true
            },
            {
                "name": "fanout",
                "description": "AMQP fanout exchange, as per the AMQP specification",
                "enabled": true
            }
        ],
        "auth_mechanisms": [
            {
                "name": "PLAIN",
                "description": "SASL PLAIN authentication mechanism",
                "enabled": true
            },
            {
                "name": "AMQPLAIN",
                "description": "QPid AMQPLAIN mechanism",
                "enabled": true
            },
            {
                "name": "RABBIT-CR-DEMO",
                "description": "RabbitMQ Demo challenge-response authentication mechanism",
                "enabled": false
            }
        ],
        "applications": [
            {
                "name": "amqp_client",
                "description": "RabbitMQ AMQP Client",
                "version": "3.5.7"
            },
            {
                "name": "inets",
                "description": "INETS  CXC 138 49",
                "version": "6.3.3"
            },
            {
                "name": "kernel",
                "description": "ERTS  CXC 138 10",
                "version": "5.1"
            },
            {
                "name": "mnesia",
                "description": "MNESIA  CXC 138 12",
                "version": "4.14.1"
            },
            {
                "name": "mochiweb",
                "description": "MochiMedia Web Server",
                "version": "2.7.0-rmq3.5.7-git680dba8"
            },
            {
                "name": "os_mon",
                "description": "CPO  CXC 138 46",
                "version": "2.4.1"
            },
            {
                "name": "rabbit",
                "description": "RabbitMQ",
                "version": "3.5.7"
            },
            {
                "name": "rabbitmq_management",
                "description": "RabbitMQ Management Console",
                "version": "3.5.7"
            },
            {
                "name": "rabbitmq_management_agent",
                "description": "RabbitMQ Management Agent",
                "version": "3.5.7"
            },
            {
                "name": "rabbitmq_web_dispatch",
                "description": "RabbitMQ Web Dispatcher",
                "version": "3.5.7"
            },
            {
                "name": "sasl",
                "description": "SASL  CXC 138 11",
                "version": "3.0.1"
            },
            {
                "name": "stdlib",
                "description": "ERTS  CXC 138 10",
                "version": "3.1"
            },
            {
                "name": "webmachine",
                "description": "webmachine",
                "version": "1.10.3-rmq3.5.7-gite9359c7"
            },
            {
                "name": "xmerl",
                "description": "XML parser",
                "version": "1.3.12"
            }
        ],
        "contexts": [
            {
                "description": "RabbitMQ Management",
                "path": "/",
                "port": "15672"
            }
        ],
        "log_file": "/opt/rabbitmq/sbin/../var/log/rabbitmq/rabbit@zhuzhonghua2-fqawb.log",
        "sasl_log_file": "/opt/rabbitmq/sbin/../var/log/rabbitmq/rabbit@zhuzhonghua2-fqawb-sasl.log",
        "db_dir": "/opt/rabbitmq/sbin/../var/lib/rabbitmq/mnesia/rabbit@zhuzhonghua2-fqawb",
        "config_files": [
            "/opt/rabbitmq/sbin/../etc/rabbitmq/rabbitmq.config (not found)"
        ],
        "net_ticktime": 60,
        "enabled_plugins": [
            "rabbitmq_management"
        ],
        "name": "rabbit@zhuzhonghua2-fqawb",
        "type": "disc",
        "running": true
    }
]

这段json中的mem_used, disk_free, socket_used, proc_used, fd_used分别对应上面监控图中的内存占用,磁盘剩余空间,Socket句柄数,Broker子进程数以及文件句柄数。



下面是一个demo代码,主要使用HttpClient以及jackson来调用相关参数。
相关maven如下:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.3.6</version>
</dependency>
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-databind</artifactId>
 <version>2.7.4</version>
</dependency>
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-annotations</artifactId>
 <version>2.7.4</version>
</dependency>
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-core</artifactId>
 <version>2.7.4</version>
</dependency>

相关代码(有点长):

package com.vms.test.zzh.rabbitmq.monitor;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import org.apache.http.HttpEntity;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by hidden on 2017/3/9.
 */
public class MonitorDemo {
    public static void main(String[] args) {
        try {
            Map<String, ClusterStatus> map = fetchNodesStatusData("http://10.198.197.73:15672/api/nodes", "root", "root");
            for (Map.Entry entry : map.entrySet()) {
                System.out.println(entry.getKey() + " : " + entry.getValue());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Map<String,ClusterStatus> fetchNodesStatusData(String url, String username, String password) throws IOException {
        Map<String, ClusterStatus> clusterStatusMap = new HashMap<String, ClusterStatus>();
        String nodeData = getData(url, username, password);
        JsonNode jsonNode = null;
        try {
            jsonNode = JsonUtil.toJsonNode(nodeData);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Iterator<JsonNode> iterator = jsonNode.iterator();
        while (iterator.hasNext()) {
            JsonNode next = iterator.next();
            ClusterStatus status = new ClusterStatus();
            status.setDiskFree(next.get("disk_free").asLong());
            status.setFdUsed(next.get("fd_used").asLong());
            status.setMemoryUsed(next.get("mem_used").asLong());
            status.setProcUsed(next.get("proc_used").asLong());
            status.setSocketUsed(next.get("sockets_used").asLong());
            clusterStatusMap.put(next.get("name").asText(), status);
        }
        return clusterStatusMap;
    }

    public static String getData(String url, String username, String password) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader(BasicScheme.authenticate(creds, "UTF-8", false));
        httpGet.setHeader("Content-Type", "application/json");
        CloseableHttpResponse response = httpClient.execute(httpGet);

        try {
            if (response.getStatusLine().getStatusCode() != 200) {
                System.out.println("call http api to get rabbitmq data return code: " + response.getStatusLine().getStatusCode() + ", url: " + url);
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity);
            }
        } finally {
            response.close();
        }

        return "";
    }

    public static class JsonUtil {
        private static ObjectMapper objectMapper = new ObjectMapper();
        static {
            objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        }

        public static JsonNode toJsonNode(String jsonString) throws IOException {
            return objectMapper.readTree(jsonString);
        }
    }

    public static class ClusterStatus {
        private long diskFree;
        private long diskLimit;
        private long fdUsed;
        private long fdTotal;
        private long socketUsed;
        private long socketTotal;
        private long memoryUsed;
        private long memoryLimit;
        private long procUsed;
        private long procTotal;
// 此处省略了Getter和Setter方法
        @Override
        public String toString() {
            return "ClusterStatus{" +
                    "diskFree=" + diskFree +
                    ", diskLimit=" + diskLimit +
                    ", fdUsed=" + fdUsed +
                    ", fdTotal=" + fdTotal +
                    ", socketUsed=" + socketUsed +
                    ", socketTotal=" + socketTotal +
                    ", memoryUsed=" + memoryUsed +
                    ", memoryLimit=" + memoryLimit +
                    ", procUsed=" + procUsed +
                    ", procTotal=" + procTotal +
                    '}';
        }
    }

}

代码输出:

rabbit@zhuzhonghua2-fqawb : ClusterStatus{diskFree=34480971776, diskLimit=0, fdUsed=38, fdTotal=0, socketUsed=1, socketTotal=0, memoryUsed=44508400, memoryLimit=0, procUsed=196, procTotal=0}
rabbit@hiddenzhu-8drdc : ClusterStatus{diskFree=36540743680, diskLimit=0, fdUsed=28, fdTotal=0, socketUsed=1, socketTotal=0, memoryUsed=53331640, memoryLimit=0, procUsed=181, procTotal=0}

更多RabbitMQ restful http api可以关注参考资料2。



欲了解更多消息中间件的内容,可以关注:消息中间件收录集


参考资料

1.http://www.rabbitmq.com/management.html
2.http://hg.rabbitmq.com/rabbitmq-management/raw-file/rabbitmq_v3_0_1/priv/www/api/index.html

时间: 2024-10-29 11:42:59

RabbitMQ之监控(1)的相关文章

RabbitMQ 队列监控

RabbitMQ 队列监控   下面脚本可以监控RabbitMQ 队列,可以看到剩余队列数量,已经增加数量.   Bash代码   #!/bin/bash   ##################################################   # Website http://www.netkiller.cn   # Author netkiller<netkiller@msn.com>   # OSCM https://github.com/oscm/shell   #

RabbitMQ之监控(2)

本文接RabbitMQ之监控(1). 不管是通过HTTP API接口还是客户端,获取的数据都是为了提供监控视图之用,不过这一切都基于RabbitMQ服务运行完好的情况下.虽然可以通过某些其他工具或方法来检测RabbitMQ进程是否在运行(如:ps aux | grep rabbitmq),或者5672端口是否开启(如:telnet xxx.xxx.xxx.xxx 5672),但是这样依旧不能真正的评判RabbitMQ是否还具备服务外部请求的能力.这里就需要使用AMQP协议来构建一个Ping的检测

RabbitMQ之监控(3)

确保RabbitMQ能够健康的运行还不足以让人放松警惕.考虑这样一种情况:小明为小张创建了一个队列并绑定了一个交换器,之后某人由于疏忽而阴差阳错的删除了这个队列而无人得知,最后小张在使用这个队列的时候就会报出"NOT FOUND"的错误.如果这些在测试环境中发生,那么还可以弥补.如果在实际生产环境中,如果误删了一个队列,那必然会造成不可估计的影响.此时业务方如果正在使用这个队列,正常情况下会立刻报出异常,相关人员迅可以迅速做出动作以尽可能的降低影响.试想如果是一个定时任务调用此队列,并

百万级PHP网站架构工具箱

在了解过世界最大的PHP站点,Facebook的后台技术后,今天我们来了解一个百万级PHP站点的网站架构:Poppen.de.Poppen.de是德国的一个社交网站,相对Facebook.Flickr来说是一个很小的网站,但它有一个很好的架构,融合了很多技术,如 Nigix.MySql.CouchDB.Erlang.Memcached.RabbitMQ.PHP.Graphite.Red5以及Tsung. Poppen.de目前有200万注册用户数.2万并发用户数.每天20万条私有消息.每天25万

消息中间件收录集

本篇主要整理工作中遇到的一些消息中间件的相关知识,包括Kafka, RabbitMQ, RocketMQ, ActiveMQ等,不排除收录其他消息中间件的可能. 这里会持续收录相关知识,包括安装.部署.使用示例.监控.运维.原理等. 所有新撰写的与中间件有关的文章都会收录与此,注意保存本文链接. Last Update Time: 2017-10-26 08:23 Update Content: RabbitMQ管理(5)--集群管理 通用 什么是Zero-Copy?(sendfile) 1.

开源 VS 商业,消息中间件你不知道的那些事

11月23日,新炬网络中间件技术专家刘拓老师在DBA+社群中间件用户组进行了一次主题为"开源 VS 商业,消息中间件你不知道的那些事"的线上分享.小编特别整理出其中精华内容,供大家学习交流.  嘉宾简介   新炬网络中间件技术专家 曾任职于IBM华南GTS 4年,IBM WebSphere.MQ.CICS产品线技术专家 5年移动运营商(广东移动.浙江移动)运维经验,3年JAVA开发及售后经验 演讲实录   随着云计算的兴起,Docker.微服务的流行,分布式消息队列技术成为云计算平台中

服务器-rabbitmq性能瓶颈与监控

问题描述 rabbitmq性能瓶颈与监控 1.是否有成熟的方法,了解rabbitmq的性能瓶颈会有哪些?,如果做到对这些性能瓶颈的监控? 2.怎样对rabbitmq server进行并发测试,使得服务器能达到性能瓶颈? 3.是否有其他现成的工具或者方法来判断是否rabbitmq到达性能瓶颈? 4.当rabbitmq到达性能瓶颈后,程序的表现是什么样的? 新人求大神指教呀!感激不尽! 解决方案 java 测试 可以考虑集群 解决方案二: java 测试 可以考虑集群 解决方案三: 压力测试工具来分

最简单的 RabbitMQ 监控方法 - 每天5分钟玩转 OpenStack(158)

  这是 OpenStack 实施经验分享系列的第 8 篇. 先来看张图: 这是 Nova 的架构图,我们可以看到有两个组件处于架构的中心位置:数据库和Queue.数据库保存状态信息,而几乎所有的 nova-* 服务都直接依赖于 Queue 实现服务之间的通信和调用. OpenStack 通常用 RabbitMQ 实现消息队列,几乎所有的 OpenStack 模块都会用到 RabbitMQ,如果 RabbitMQ 挂了,OpenStack 也就瘫了,可以说它是最重要的组件. 本节我们就来讨论如何

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

1.通过 rabbitmqctl 脚本  rabbitmqctl 是 shell 脚本,其通过 exec 调用了 erl 程序.会间接调用到如下两个 shell 脚本:  rabbitmq-env rabbitmq-defaults 在使用该脚本时允许用户定制的环境变量为:  RABBITMQ_NODENAME          默认值 ${NODENAME} RABBITMQ_CTL_ERL_ARGS       默认值 ${CTL_ERL_ARGS} 下面分别看下这几个脚本都干了哪些事情.[