RabbitMQ之监控(1)

简介: RabbitMQ作为一个工业级的消息中间件,肯定是缺少不了监控的,RabbitMQ提供了WEB版的页面监控(访问地址:http://xxx.xxx.xxx.xxx:15672/,默认端口号是15672。

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

相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
消息中间件 监控 数据可视化
SpringCloud进阶:一文通透RabbitMQ服务监控
前面我们介绍了通过turbine直接聚合多个服务的监控信息,实现了服务的监控,但是这种方式有个不太好的地方就是turbine和服务的耦合性太强了,针对这个问题,我们可以将服务的监控消息发送到RabbitMQ中,然后turbine中RabbitMQ中获取获取监控消息,这样就实现类服务和turbine的解耦。 我们通过案例来演示下如何实现该效果 一、启动RabbitMQ服务 显然我们需要安装启动一个RabbitMQ服务 二、创建consumer服务 创建一个consumer服务,同时要将dashboard的监控信息发送到RabbitMQ服务中。 1.创建项目
138 0
SpringCloud进阶:一文通透RabbitMQ服务监控
|
消息中间件 监控 前端开发
RabbitMQ 的监控
上两篇文章介绍了: Mac 环境下 RabbitMQ 的安装 RabbitMQ 的六种工作模式(附 Python 代码)
439 0
RabbitMQ 的监控
|
消息中间件 Prometheus 监控
prometheus+grafana监控rabbitmq
prometheus+grafana监控rabbitmq
686 0
prometheus+grafana监控rabbitmq
|
消息中间件 监控 API
|
消息中间件 监控 数据库
RabbitMQ之监控(3)
确保RabbitMQ能够健康的运行还不足以让人放松警惕。考虑这样一种情况:小明为小张创建了一个队列并绑定了一个交换器,之后某人由于疏忽而阴差阳错的删除了这个队列而无人得知,最后小张在使用这个队列的时候就会报出“NOT FOUND”的错误。
1360 0
|
消息中间件 监控 API
RabbitMQ之监控(2)
本文接RabbitMQ之监控(1)。 不管是通过HTTP API接口还是客户端,获取的数据都是为了提供监控视图之用,不过这一切都基于RabbitMQ服务运行完好的情况下。虽然可以通过某些其他工具或方法来检测RabbitMQ进程是否在运行(如:ps aux | grep rabbitmq),或者5672端口是否开启(如:telnet xxx.xxx.xxx.xxx 5672),但是这样依旧不能真正的评判RabbitMQ是否还具备服务外部请求的能力。
1529 0
|
消息中间件 监控 Shell
|
消息中间件 监控 PHP
rabbitmq消息件在idc机房监控中的应用
原文见http://www.linuxboy.net/wordpress2/2009/05/31/295.html   rabbitmq-server是一个消息中间件,由erlang语言写就。
934 0
|
8月前
|
消息中间件 Linux
centos7 yum快速安装rabbitmq服务
centos7 yum快速安装rabbitmq服务
137 0