文档章节

RabbitMQ监控(一):使用AMQP模拟检测来确认RabbitMQ是否运行

大光头兰翔
 大光头兰翔
发布于 2017/05/02 16:23
字数 1241
阅读 432
收藏 1

#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

/**
 * 健康检测程序的几种状态
 */
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构造一个健康检测程序来进行完整的生产/消费测试。

© 著作权归作者所有

大光头兰翔
粉丝 13
博文 5
码字总数 5403
作品 0
私信 提问
加载中

评论(2)

大光头兰翔
大光头兰翔 博主

引用来自“sunzhanpe”的评论

火钳刘明,顶起来!按时更新哦!
😬谢谢占鹏,你已经是一名合格的水军啦
sunzhanpe
sunzhanpe
火钳刘明,顶起来!按时更新哦!
Docker安装部署RabbitMQ、PHP安装扩展AMQP及测试

一、使用Docker安装部署RabbitMQ 1、docker search rabbitmq:management 2、docker pull rabbitmq:management 注:如果docker pull rabbitmq 后面不带management,启动rabbitmq后是无法打开管......

老查
2018/11/06
0
0
【原创】rabbitmq-server用户手册(翻译)

为了方便工作中使用,周末抽空对rabbitmq-server用户手册进行了翻译,鉴于自己水平有限,翻译中难免有纰漏产生,如果疑问,欢迎指出探讨。 官方原文:http://www.rabbitmq.com/man/rabbitmq-...

摩云飞
2012/11/12
0
0
Linux下build和使用rabbitmq-c

按照这里介绍的方法,先安装CMake 2) 在这里找到下载link,下载rabbitmq-c的包 3) 解压,进入解压后的目录 4) mkdir build && cd build # 这一步是在rabbitmq-c的根目录下创建一个build子目录...

mac_zhao
2014/09/28
0
0
(一)RabbitMQ消息队列-RabbitMQ的优劣势及产生背景

本篇并没有直接讲到技术,例如没有先写个Helloword。我想在选择了解或者学习一门技术之前先要明白为什么要现在这个技术而不是其他的,以免到最后发现自己学错了。同时如果已经确定就是他,最...

Super_RD
2017/04/18
0
0
RabbitMQ与Redis队列对比

本文仅针对RabbitMQ与Redis做队列应用时的情况进行对比 具体采用什么方式实现,还需要取决于系统的实际需求 简要介绍 RabbitMQ RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,...

凯文加内特
2015/05/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Linux的基本命令

目录的操作命令(增删改查) 增: mkdir 目录名称; 查: ls 可以看到该目录下的所有的目录和文件 ls -a,可以看到该目录下的所有文件和目录,包括隐藏的 ls -l,可以看到该目录下的所有目录和...

凹凸凸
今天
2
0
在古老unix中增加新用户

Installing 4.3 BSD Quasijarus on SIMH 目标:要在4.3BSD中新增加用户dmr,指定目录/home/dmr,uid为10 gid=31(guest组,系统已建立) 4.3BSD还没有adduser或useradd 直接修改/etc/passwd...

wangxuwei
今天
2
0
Bootstrap(六)表单样式

基本样式 所有设置了 .form-control 类的 <input>、<textarea> 和 <select> 元素都将被默认设置宽度属性为 width: 100%;。 将 label 元素和前面提到的控件包裹在 .form-group 中可以获得最好...

ZeroBit
昨天
3
0
SSL 证书格式转换

SSL 证书格式转换 不同服务器情况下,需要不同的证书格式。 比如 pem 转 pfx。 pem在window 平台下可以导入,但是无法正常使用。 需要转换成pfx。 推荐在线转换工具,由中国数字证书网站提供...

DrChenXX
昨天
2
0
HAProxy

xx

Canaan_
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部