我正在参加「掘金·启航计划」
Apache ActiveMQ是一个开源的java消息中间件。activemq默认端口包括服务端口61616,jetty提供的web管理端口8161,jmx端口1099/11099,jmx端口一般用于暴露监控数据。
可用性影响及高可用策略
最简单高可用策略为在每个机房分别部署两个互相独立的activemq,客户端应用将两个activemq配进failover策略,单个activemq不可用时,客户端可以连接另外一个,缺点是生产者的消息必须由消费者连到同一个mq上才能消费,如果这个mq挂了,消息需要等该mq恢复后才可以访问。
另一种方式使用的是Broker-Cluster模式,通过配置networkConnectors将两个broker连接起来,实现负载均衡,配置如下:
<networkConnectors>
<networkConnector uri="static:(tcp://other-broker:port)" duplex="true" />
<networkConnectors>
还有一种模式,即基于共享文件系统或共享数据库的master-slave模式,在某个时间,获得共享文件锁的实例即为主实例,客户端配置failover连接策略。该模式应注意共享文件系统保持高可用,否则共享文件系统为单点,则整个系统也是单点。
数据持久化
KahaDB的持久化机制基于kahadb的日志文件,索引和缓存。如果消息发送成功,则变标记为可删除的,系统周期性的清除或者归档日志文件。
注意:长期未消费的消息,导致持久化日志无法删除,实例占用的存储空间过大,需定期进行清理(比如死信消息)。为避免影响,注意以下事项:
- storeUsage配置不宜过小,与业务开发协商制定合适的过期消息及空队列清理策略。
- 容器部署时,kahadb日志文件pagecache没有及时清理,需要进行手动清理。
## 驱逐activemq过期日志pagecache
0 * * * * find /home/ctrs/activemq/data -name "*log" -mtime +1 -mtime -3 -exec vmtouch -e {} \;
部署方法
- actviemq没有官方的容器镜像,使用容器部署时,需自行构建镜像(确定版本,构建镜像,上传镜像仓库)
- 确定主备模式,包括主备互相独立,static networkConnector,共享文件系统等
- 确定数据库持久化方式,一般为kahadb
- 确定部署主机,路径,资源,参考已有项目部署目录,拷贝相关目录、文件,修改账号密码等相关配置
- 各节点启动实例,并检查日志
- 前台登录,检查
- 配置监控采集
监控配置
activemq是java应用,一般使用jmx exporter对其进行监控。JMX 是 Java Management Extensions 的缩写,是管理 Java 的一种扩展框架,JMX Exporter 正是基于此框架来读取 JVM 的运行时状态的。JMX Exporter 由 Prometheus 官方提供,其运行有两种方式,一是作为 java agent 与 activemq 运行在同一进程(官方推荐),二是作为独立的 http server 运行。具体参考官网。
部署完成后在prometheus进行指标采集及告警。 一般对连接数,消息队列长度进行监控告警:
- alert: mq连接数过高
expr: activemq_connections > 1000
labels:
severity: Warning
annotations:
summary: "{{ $labels.instance }}连接数 => {{ $value }}"
- alert: mq消息积压
expr: org_apache_activemq_Broker_QueueSize{destinationName!="ActiveMQ.DLQ"} > 200 or activemq_queue_queue_size{destination!="ActiveMQ.DLQ"} > 0
for: 1h
labels:
severity: Average
threshold: ">200 for 1h"
annotations:
summary: "MQ:{{ $labels.instance }}:{{ $labels.destinationName }}消息积压 => {{ $value }}"
- alert: mq消息积压
expr: org_apache_activemq_Broker_QueueSize{destinationName!~"ActiveMQ\.DLQ|queue.notify\.account.*|settle.*"} > 200 or org_apache_activemq_Broker_QueueSize{destinationName=~"queue.notify\.account.*|settle.*"} > 200000 or activemq_queue_queue_size{destination!="ActiveMQ.DLQ"} > 200
for: 2m
labels:
severity: Warning
threshold: ">200"
annotations:
summary: "MQ:{{ $labels.instance }}:{{ $labels.destinationName }}消息积压 => {{ $value }}"