本系列是「RabbitMQ实战:高效部署分布式消息队列」书籍的总结笔记。
上一篇总结了可能出现的异常场景,并对RabbitMQ提供的可用性保证进行了分析,在出现服务器宕机后,仍然可以正常服务。另外,需要尽快恢复异常的服务器,重新加入集群,推送未消费的消息,通过监控可第一时间接收到错误并进行处理。
另外,我们想主动了解消息堆积和消费的情况,以及服务器节点的压力,RabbitMQ提供了几种方式便捷、直观的了解,包括Web管理插件、REST API、rabbitmqadmin脚本。
通过介绍,你会了解到:
RabbitMQ的插件是由Erlang语言写的,并且和服务器一同运行在同一个Erlang VM中,通过下面的命令启用web管理插件:
sudo ./rabbitmq-plugins enable rabbitmq_management
启动之后,访问15672端口,可看到Web管理页面主页面:
默认会提供一个默认用户guest,密码也是guest,线上环境需要创建一个新用户,并把guest用户删除。
首先切换到Admin标签页,可以查看或添加用户,添加用户时,可指定Tags,相当于角色,会拥有对应的权限:
点击用户列表的用户名,可分配权限、编辑或删除用户,分配权限时,可细化到某个virtual下的某个topic,并按读、写、配置类别进行分开:
切换到“Exchanges”标签,可查看和管理交换器,单击交换器名称,可查看到更多详细信息,比如交换器绑定,还可以添加新的绑定:
切换到“Queues”标签,可以查看队列信息,点击队列名称,可查看队列所有状态的消息数量和大小等统计信息:
还可以查看消费者和绑定,发布、获取消息:
有时需要初始化一些列队列和交换器,每次部署一套新环境后,都需要一步一步创建会有点麻烦,通过REST API可方便的实现自动化脚本。
当启用web管理插件后,不仅获得了WEB UI,也拥一个REST化的WEB管理API,任何语言或脚本只要有HTTP库,都能调用。
接口会返回json串,比如获取所有队列:
curl -i -u admin:admin http://localhost:15672/api/queues
会返回一个json数组,每个元素是一个队列,包含队列的各种属性:
另外,还提供了rabbitmqadmin脚本的方式查看元数据信息和一些统计数据,它会包装REST API,使用干净的接口与其交互,而且输出内容也是格式化过的,方便我们查看。
比如查看所有队列,可以这样写:
./rabbitmqadmin list queues
会返回如下结果:
监控RabbitMQ并不只是确保端口5672是开启的并能接收TCP连接而已,还要能够模拟AMQP客户端来确保连接之后获取信道,如果能使用REST API找出是否所有构成RabbitMQ部件都正常运行,并且之间能正常通信,就更好了。
书中介绍使用Nagios监控框架进行监控,我之前没有使用,这里搜集了一些资料,会做下简单介绍。
Nagios是一款开源的监控工具,能有效监控Windows、Linux和Unix的主机状态,交换机路由器等网络设置,打印机等。在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员,在状态恢复后发出正常的邮件或短信通知。
它本身不包括这部分功能,所有的监控、检测功能都是通过各种插件完成的,启动Nagios后,它会周期性的自动调用插件去检测服务器状态,同时Nagios会维持一个队列,所有插件返回来的状态信息都进入队列,Nagios每次都从队首开始读取信息,并进行处理后,把状态结果通过web显示出来。
Nagios可以识别4种状态返回信息:
Nagios根据插件返回来的值,来判断监控对象的状态,并通过web显示出来,以供管理员及时发现故障。
它是如何管理远端服务器对象的,使用NRPE插件,主要过程如下:
书中提到监控RabbitMQ的各个方面,比如:监控Rabbit内部状态、确认RabbitMQ可用并且能够响应、观察队列状态检测消费者异常、检测消息通信结构中不合需求的配置更改等。
基本思路都是通过编写Nagios需要的检测脚本,使用AMQP客户端或REST API的方式,获取关心的监控信息,根据情况返回不同的状态码。
具体的脚本脚本就不一一介绍了,这里举个例子,监控队列的持久化配置是否正确,通过api/queues//获取队列信息,判断它的durable属性是否为true,脚本如下:
import sys, json, httplib, urllib, base64, socket
# 1.定义状态码
EXIT_OK = 0
EXIT_WARNING = 1
EXIT_CRITICAL = 2
EXIT_UNKNOWN = 3
# 2.解析参数
server, port = sys.argv[1].split(":")
vhost = sys.argv[2]
username = sys.argv[3]
password = sys.argv[4]
queue_name = sys.argv[5]
auto_delete = json.loads(sys.argv[6].lower())
durable = json.loads(sys.argv[7].lower())
# 3.连接服务器
conn = httplib.HTTPConnection(server, port)
# 4.构建api路径
path = "/api/queues/%s/%s" % (urllib.quote(vhost, safe=""),
urllib.quote(queue_name))
method = "GET"
# 5.执行http请求
credentials = base64.b64encode("%s:%s" % (username, password))
try:
conn.request(method, path, "",
{"Content-Type" : "application/json",
"Authorization" : "Basic " + credentials})
# 6.连接异常,退出
except socket.error:
print "UNKNOWN: Could not connect to %s:%s" % (server, port)
exit(EXIT_UNKNOWN)
response = conn.getresponse()
# 7.状态码为404,说明队列不存在,退出
if response.status == 404:
print "CRITICAL: Queue %s does not exist." % queue_name
exit(EXIT_CRITICAL)
# 8.durable属性是否正确
if response["durable"] != durable:
print "WARN: Queue '%s' - durable flag is NOT %s." % \
(queue_name, durable)
exit(EXIT_WARNING)
# 9.返回正常
print "OK: Queue %s configured correctly." % queue_name
exit(EXIT_OK)
下一篇将介绍RabbitMQ安全和性能方面的考虑。
欢迎扫描下方二维码,关注我的个人微信公众号 ~