欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


欢迎跳转到本文的原文链接:https://honeypps.com/mq/rabbitmq-monitor-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": "xx.xx.197.73","peer_port": 25672,"sock_addr": "xx.xx.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": "xx.xx.198.10","peer_port": 29226,"sock_addr": "xx.xx.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://xx.xx.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方法@Overridepublic 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

欢迎跳转到本文的原文链接:https://honeypps.com/mq/rabbitmq-monitor-1/


欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


RabbitMQ之监控(1)相关推荐

  1. RabbitMQ之监控(2)

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  2. RabbitMQ之监控(3)

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  3. java监控rabbitMq服务状态,SpringCloud-Turbine【RabbitMQ服务监控】

    前面我们介绍了通过turbine直接聚合多个服务的监控信息,实现了服务的监控,但是这种方式有个不太好的地方就是turbine和服务的耦合性太强了,针对这个问题,我们可以将服务的监控消息发送到Rabbi ...

  4. RabbitMQ队列监控

    Idle:通过自动发现队列,获取各个队列中的ready,unackd等值 sudo !!! 1 #!/bin/sh 2 discovery(){ 3 Queue=(`rabbitmqctl list_ ...

  5. rabbitmq接口异常函数方法_RabbitMQ监控(三):监控队列状态

    #RabbitMQ 监控(三) 验证RabbitMQ健康运行只是确保消息通信架构可靠性的一部分,同时,你也需要确保消息通信结构配置没有遭受意外修改,从而避免应用消息丢失. RabbitMQ Manag ...

  6. RabbitMQ学习之队列监控

    对于RabbitMQ的监控,除了服务器基本信息(硬盘.CPU.内存.IO等)以及MQ的进程和端口,我们也可以通过请求url访问管理API监控其集群和队列的情况.在Java api 3.6.0以后,ch ...

  7. kafka学习_《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 RabbitMQ

    前言 之前有文章 <从0到1学习Flink>-- Flink 写入数据到 Kafka 写过 Flink 将处理后的数据后发到 Kafka 消息队列中去,当然我们常用的消息队列可不止这一种, ...

  8. 队列工厂之RabbitMQ

    本次和大家分享的是RabbitMQ队列的用法,前一篇文章队列工厂之(MSMQ)中在描述的时候已经搭建了简单工厂,因此本章内容是在其之上扩充的子项不再过多讲解工厂的代码了:RabbitMQ应该是现在互联 ...

  9. 消息中间件(Kafka/RabbitMQ)收录集

    本篇主要整理工作中遇到的一些消息中间件的相关知识,包括Kafka, RabbitMQ, RocketMQ, ActiveMQ等,不排除收录其他消息中间件的可能. 这里会持续收录相关知识,包括安装.部署 ...

最新文章

  1. UCenter创始人密码正确但是登录不了
  2. CentOS 7源码安装httpd服务
  3. 阿里云函数计算 FC再次荣获最受观众喜爱奖
  4. 谈谈战双的战斗机制设计趋同
  5. 基于Echarts的HTML5 Canvas折线图DEMO演示
  6. C/S、B/S的区别
  7. DB Query Analyzer中的事务管理在DB2中的应用
  8. python flask服务器假死_python – Flask POST请求导致服务器崩溃
  9. oracle desc卡,Oracle的一个bug,desc的bug,很夸张,这么基础的功能居然有bug
  10. tushare 安装
  11. 蓝桥杯 ALGO-68 算法训练 判定数字
  12. 阿里,百度,腾讯等一线互联网公司中,Java开发的招聘标准
  13. 计算机管理格式化没有顺利完成,内存卡无法格式化
  14. python绘制太阳花_Python绘制蟒蛇和太阳花
  15. Java项目:赛事打分系统(java+SSM+Layui+Maven+mysql)
  16. 响应式网页设计与应用
  17. 超给力,一款简单又实用的免费 GitHub 加速神器
  18. 微信红包业务,为什么采用轮询算法?
  19. 第八周---FPGA流水灯显示和串口循环输出实验
  20. 酷睿计算机系统吗,酷睿i3和i5的区别是什么?电脑处理器i3和i5的区别介绍

热门文章

  1. Spring Boot Transaction 源码解析(一)
  2. win32 输出文字时清除之前的_努力学习没效果?3个步骤,强化沟通输出,实现飞跃式成长...
  3. 用 Redis 实现分布式锁(Java 版)
  4. web开发的跨域问题详解
  5. 批量生成100万张小程序码?了解一下。
  6. Python爬虫小实践:寻找失踪人口,爬取失踪儿童信息并写成csv文件,方便存入数据库...
  7. shaderlab UV动画所需的变量声明
  8. 【C语言位运算的应用】如何按bit位翻转一个无符号整型
  9. Linux同一网段使用不同网卡的方法
  10. 关于程序中查询效率的问题