RabbitMQ监控(一):使用AMQP模拟检测来确认RabbitMQ是否运行
2017-05-04 14:09
253 查看
#RabbitMQ 监控(一)
本RabbitMQ监控博文内容均来自于《RabbitMQ实战高效部署分布式消息队列》一书。书籍上的代码是使用Python实现的,我用Java尝试了一下,该系列代码都在我的github上。
监控RabbitMQ并不只是确保端口5672是开启的并能接收TCP连接而已,对于这样复杂的系统,需要能够模拟AMQP客户端来确保连接之后获取信道、使用REST API来找出所有构成Rabbit的Erlang部件都正常运行,并且它们之间能正确通信的话才能算是一个完整的健康检测程序。
##1.为Nagios编写健康检测
我对监控框架不是很了解,只知道我司使用的是Zabbix,Zabbix也支持多语言、自定义监控脚本等。Nagios健康检测是一个独立的程序,它在运行时监控服务并在程序终止运行时退出代码来指示服务的健康状况。Nagios健康检测可以用任何语言编写,检测程序需要将可读状态打印到STDOUT上,并且返回下列四种整形退出代码之一:
* 0——OK——接收检测的服务工作正常,并且各项指标都处于通过命令行参数设定的阀值之内。
* 1——WARNING——服务运行处于退化状态(或者说是遇到了问题),但是这个问题并不紧急。
* 2——CRITICAL——服务关闭了,无响应,并且/或者超过了受监控的临界度量阀值。
* 3——UNKNOWN——从技术上来讲,这意味着服务的状态或者监控的度量值无法确定。
在理解Nagios期望从健康检测程序中获得的值之后,首先需要编写一个返回Nagios状态代码的健康检测程序。
###清单1.1 返回Nagios状态代码的健康检测程序
1.状态码枚举 ExitType.java
2.返回Nagios状态码 ExitUtil.java
##2.使用AMQP模拟检测来确认RabbitMQ是否运行
不用编写代码,大多数监控系统附带的TCP健康检测程序都能通过TCP连接测试RabbitMQ是否能在端口上响应。虽然这会告诉你RabbitMQ守护进程是否在运行,但却不能知道它是否正常运作。为了能够真正的判断RabbitMQ是否有能力来服务请求,你需要真实地发送AMQP命令,在这里构造一个AMQP ping健康检测,当下列任何条件之一为真时,该检测程序会返回一个critical状态。仅当这些状态检测都为false时,健康检测程序才会返回OK状态。
* RabbitMQ没有响应TCP连接
* 当发送AMQP命令时,在接收到响应之前超时了。
* 当构造AMQP信道时,遇到了协议错误
###清单2.1 模拟AMQP检测RabbitMQ是否运行
1.RabbitMQ配置文件 rabbitmq-cfg.properties
2.读取配置文件 RMQConfig.java
3.创建RabbitMQ连接 ConnectionUtil.java
4.检测RabbitMQ状态 AMQPPingCheck.java
5.运行检测程序
可以看到健康检测程序正常工作:
16:12:57.912 [main] INFO com.lanxiang.rabbitmqmonitor.check.AMQPPingCheck - OK: Connect to 127.0.0.1 successful.
16:12:57.914 [main] INFO com.lanxiang.rabbitmqmonitor.terminate.ExitUtil - Status is OK
##下一章将介绍使用REST API构造一个健康检测程序来进行完整的生产/消费测试。
本RabbitMQ监控博文内容均来自于《RabbitMQ实战高效部署分布式消息队列》一书。书籍上的代码是使用Python实现的,我用Java尝试了一下,该系列代码都在我的github上。
监控RabbitMQ并不只是确保端口5672是开启的并能接收TCP连接而已,对于这样复杂的系统,需要能够模拟AMQP客户端来确保连接之后获取信道、使用REST API来找出所有构成Rabbit的Erlang部件都正常运行,并且它们之间能正确通信的话才能算是一个完整的健康检测程序。
##1.为Nagios编写健康检测
我对监控框架不是很了解,只知道我司使用的是Zabbix,Zabbix也支持多语言、自定义监控脚本等。Nagios健康检测是一个独立的程序,它在运行时监控服务并在程序终止运行时退出代码来指示服务的健康状况。Nagios健康检测可以用任何语言编写,检测程序需要将可读状态打印到STDOUT上,并且返回下列四种整形退出代码之一:
* 0——OK——接收检测的服务工作正常,并且各项指标都处于通过命令行参数设定的阀值之内。
* 1——WARNING——服务运行处于退化状态(或者说是遇到了问题),但是这个问题并不紧急。
* 2——CRITICAL——服务关闭了,无响应,并且/或者超过了受监控的临界度量阀值。
* 3——UNKNOWN——从技术上来讲,这意味着服务的状态或者监控的度量值无法确定。
在理解Nagios期望从健康检测程序中获得的值之后,首先需要编写一个返回Nagios状态代码的健康检测程序。
###清单1.1 返回Nagios状态代码的健康检测程序
1.状态码枚举 ExitType.java
/** * 健康检测程序的几种状态 */ public enum ExitType { WARN("warning"), CRITICAL("critical"), UNKNOWN("unknown"), OK("ok"); private String value; ExitType(String value) { this.value = value; } public String getValue() { return this.value; } }
2.返回Nagios状态码 ExitUtil.java
/** * 接收状态码,并以Nagios状态码退出 */ public class ExitUtil { private final static Logger log = LoggerFactory.getLogger(ExitUtil.class); public static void exit(String type) { if (type.equalsIgnoreCase("warning")) { log.info("Status is WARN"); System.exit(1); } else if (type.equalsIgnoreCase("critical")) { log.info("Status is CRITICAL"); System.exit(2); } else if (type.equalsIgnoreCase("unknown")) { log.info("Status is UNKNOWN"); System.exit(3); } else if (type.equalsIgnoreCase("ok")) { log.info("Status is OK"); System.exit(0); } else { log.error("Unknown exit type"); System.exit(-1); } } }
##2.使用AMQP模拟检测来确认RabbitMQ是否运行
不用编写代码,大多数监控系统附带的TCP健康检测程序都能通过TCP连接测试RabbitMQ是否能在端口上响应。虽然这会告诉你RabbitMQ守护进程是否在运行,但却不能知道它是否正常运作。为了能够真正的判断RabbitMQ是否有能力来服务请求,你需要真实地发送AMQP命令,在这里构造一个AMQP ping健康检测,当下列任何条件之一为真时,该检测程序会返回一个critical状态。仅当这些状态检测都为false时,健康检测程序才会返回OK状态。
* RabbitMQ没有响应TCP连接
* 当发送AMQP命令时,在接收到响应之前超时了。
* 当构造AMQP信道时,遇到了协议错误
###清单2.1 模拟AMQP检测RabbitMQ是否运行
1.RabbitMQ配置文件 rabbitmq-cfg.properties
host=127.0.0.1 port=5672 username=guest password=guest rmq_url=http://127.0.0.1:15672
2.读取配置文件 RMQConfig.java
public class RMQConfig { private final String host; private final int port; private final String username; private final String password; //RabbitMQ REST API URL private final String rmqUrl; private RMQConfig() throws IOException { Properties properties = new Properties(); //读取resources下的properties文件 properties.load(getClass().getClassLoader().getResourceAsStream("rabbitmq-cfg.properties")); host = properties.getProperty("host"); port = Integer.valueOf(properties.getProperty("port")); username = properties.getProperty("username"); password = properties.getProperty("password"); rmqUrl = properties.getProperty("rmq_url"); } public String getHost() { return host; } public int getPort() { return port; } public String getUsername() { return username; } public String getPassword() { return password; } public String getRmqUrl() { return rmqUrl; } public enum Singleton { INSTANCE; private RMQConfig rmqConfig; Singleton() { try { rmqConfig = new RMQConfig(); } catch (IOException e) { e.printStackTrace(); } } public RMQConfig getRmqConfig() { return rmqConfig; } } }
3.创建RabbitMQ连接 ConnectionUtil.java
/** * 获取RabbitMQ连接 */ public class ConnectionUtil { public static Connection getConnection() throws IOException, TimeoutException { RMQConfig config = RMQConfig.Singleton.INSTANCE.getRmqConfig(); String host = config.getHost(); int port = config.getPort(); String username = config.getUsername(); String password = config.getPassword(); ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setPort(port); factory.setUsername(username); factory.setPassword(password); return factory.newConnection(); } public static Connection getConnection(String host, int port, String username, String password) throws IOException, TimeoutException { ConnectionFactory factory = new ConnectionFactory(); factory.setHost(host); factory.setPort(port); factory.setUsername(username); factory.setPassword(password); return factory.newConnection(); } }
4.检测RabbitMQ状态 AMQPPingCheck.java
/** * 检测能否创建RabbitMQ连接 */ public class AMQPPingCheck { private final static Logger log = LoggerFactory.getLogger(AMQPPingCheck.class); public static void checkAMQPPing() { RMQConfig config = RMQConfig.Singleton.INSTANCE.getRmqConfig(); String host = config.getHost(); int port = config.getPort(); String username = config.getUsername(); String password = config.getPassword(); Connection connection = null; try { connection = ConnectionUtil.getConnection(host, port, username, password); } catch (IOException | TimeoutException e) { log.error("Critical : Could not connect to {}, cause {}", host, e.getMessage()); ExitUtil.exit(ExitType.CRITICAL.getValue()); } log.info("OK: Connect to {} successful.", host); ExitUtil.exit(ExitType.OK.getValue()); } }
5.运行检测程序
[@Test](https://my.oschina.net/azibug) public void pingCheck() { AMQPPingCheck.checkAMQPPing(); }
可以看到健康检测程序正常工作:
16:12:57.912 [main] INFO com.lanxiang.rabbitmqmonitor.check.AMQPPingCheck - OK: Connect to 127.0.0.1 successful.
16:12:57.914 [main] INFO com.lanxiang.rabbitmqmonitor.terminate.ExitUtil - Status is OK
##下一章将介绍使用REST API构造一个健康检测程序来进行完整的生产/消费测试。
相关文章推荐
- C#-webBrowser-登录-数据填充-模拟点击链接-运行JS函数-检测网页是否载入完成
- RabbitMQ监控(二):使用REST API来检测
- 熙熙-C#-webBrowser-登录-数据填充-模拟点击链接-运行JS函数-检测网页是否载入完成
- Android使用工具方法-检测服务是否正在运行
- Smart Client Software Factory :使用 Visualizer 监控 SCSF 运行状态
- 安装程序自动检测安装.Net Framework运行环境(使用InnoSetup)
- FindWindow(api)确认程序是否在运行
- 使用JRockit Mission Control监控Java程序运行性能
- 利用Ajax返回用户ID是否已被使用的检测信息
- C#使用HTTP头检测网络资源是否有效
- 数据验证(模拟检测用户名是否存在) http://www.cnblogs.com/beniao/archive/2008/03/29/1129141.html
- 检测你的程序是否运行在虚拟机(VMware)
- 检测代码运行效率 GetTickCount()的使用
- 如何使用命令方式检测mx记录是否生效
- 如何使用命令方式检测mx记录是否生效
- 检测代码运行效率 GetTickCount()的使用
- 用dos批处理程序检测是否安装.netframework,并自动安装后运行指定程序(.net自启动光盘的制做)
- 使用datalist删除前提示,要求用户确认是否删除的做法
- 使用datalist删除前提示,要求用户确认是否删除的做法
- 如何使用命令方式检测mx记录是否生效