在使用任何消息中间件的过程中,难免会出现某条消息异常丢失的情况。对于RabbitMQ而言,可能是因为生产者或消费者与RabbitMQ断开了连接,而它们与RabbitMQ又采用了不同的确认机制;也有可能是因为交换器与队列之间不同的转发策略;甚至是交换器并没有与任何队列进行绑定,生产者又不感知或者没有采取相应的措施;另外RabbitMQ本身的集群策略也可能导致消息的丢失。这个时候就需要有一个较好的机制跟踪记录消息的投递过程,以此协助开发和运维人员进行问题的定位。
在RabbitMQ中可以使用 Firehose 和 rabbitmq_tracing插件 功能来实现消息追踪。
firehose的机制是将生产者投递给rabbitmq的消息,rabbitmq投递给消费者的消息按照指定的格式发送到默认的exchange上。这个默认的exchange的名称为
amq.rabbitmq.trace
,它是一个topic类型的exchange。发送到这个exchange上的消息的routing key为publish.exchangename
和deliver.queuename
。其中exchangename和queuename为实际exchange和queue的名称,分别对应生产者投递到exchange的消息,和消费者从queue上获取的消息。注意:
打开 trace 会影响消息写入功能,适当打开后请关闭。
开启Firehose命令:
[root@localhost ~]# rabbitmqctl trace_on
关闭Firehose命令:
[root@localhost ~]# rabbitmqctl trace_off
注: 以上两条命令会默认开启/关闭RabbitMQ默认的虚拟主机“/”
的Firehose功能,不推荐。
推荐命令(操作指定主机域的Firehose功能):
rabbitmqctl trace_on -p 虚拟主机名
rabbitmqctl trace_off -p 虚拟主机名
① 开启Firehose:
[root@localhost ~]# rabbitmqctl trace_on -p /myhost
Starting tracing for vhost "/myhost" ...
[root@localhost ~]#
② 手动添加测试队列test_queue_trace
③ 将RabbitMQ内部提供的交换机amq.rabbitmq.trace绑定测试队列test_queue_trace
⑤ 获取测试队列test_queue_trace中的消息
说明: 发现消息中,除我们自己发送的1条消息外,amq.rabbitmq.trace队列会自动发送多条更加详细的消息记录,以方便我们自己的消息丢失时,可以追踪相关原因。
注意:
打开 trace 会影响消息写入功能,适当打开后请关闭。
测试完毕,为不影响RabbitMQ性能(特别是生产环境),请关闭Firehost功能。
[root@localhost ~]# rabbitmqctl trace_off -p /myhost
Stopping tracing for vhost "/myhost" ...
[root@localhost ~]#
rabbitmq_tracing和Firehose在实现上如出一辙,只不过rabbitmq_tracing的方式比Firehose多了一层GUI的包装,更容易使用和管理。
[root@localhost ~]# rabbitmq-plugins list
Configured: E = explicitly enabled; e = implicitly enabled
| Status: * = running on rabbit@localhost
|/
[e*] amqp_client 3.6.5
[ ] cowboy 1.0.3
[ ] cowlib 1.0.1
[e*] mochiweb 2.13.1
[ ] rabbitmq_amqp1_0 3.6.5
[ ] rabbitmq_auth_backend_ldap 3.6.5
[ ] rabbitmq_auth_mechanism_ssl 3.6.5
[ ] rabbitmq_consistent_hash_exchange 3.6.5
[ ] rabbitmq_event_exchange 3.6.5
[ ] rabbitmq_federation 3.6.5
[ ] rabbitmq_federation_management 3.6.5
[ ] rabbitmq_jms_topic_exchange 3.6.5
[E*] rabbitmq_management 3.6.5
[e*] rabbitmq_management_agent 3.6.5
[ ] rabbitmq_management_visualiser 3.6.5
[ ] rabbitmq_mqtt 3.6.5
[ ] rabbitmq_recent_history_exchange 1.2.1
[ ] rabbitmq_sharding 0.1.0
[ ] rabbitmq_shovel 3.6.5
[ ] rabbitmq_shovel_management 3.6.5
[ ] rabbitmq_stomp 3.6.5
[ ] rabbitmq_top 3.6.5
[ ] rabbitmq_tracing 3.6.5
[ ] rabbitmq_trust_store 3.6.5
[e*] rabbitmq_web_dispatch 3.6.5
[ ] rabbitmq_web_stomp 3.6.5
[ ] rabbitmq_web_stomp_examples 3.6.5
[ ] sockjs 0.3.4
[e*] webmachine 1.10.3
[root@localhost ~]#
[root@localhost ~]# rabbitmq-plugins enable rabbitmq_tracing
The following plugins have been enabled:
rabbitmq_tracing
Applying plugin configuration to rabbit@localhost... started 1 plugin.
[root@localhost ~]#
我们可以在RabbitMQ的web管理页面看到:插件已启动成功
添加测试trace报错:
trace配置说明:
- Name:即将创建的trace的名称
- Format:表示输出消息日志的格式,有Text和JSON两种,Text格式方便人类阅读,JSON格式方便程序解析
- Max payload bytes:表示每条消息的最大限制,单位为B。比如设置了此值为10,那么当有超过10B的消息经过RabbitMQ流转时就会被载断,如:trace test payload会被载断成trace test。
- Pattern用来设置匹配的模式,和Firehose类似,详解如下:
① "publish.#"匹配发送至所有交换器的消息
② “deliver.#"匹配消费所有队列的消息
③ “#”包含“publish.#“和“deliver.#”
④ "publish.test_exchange"匹配发送到指定交换器的消息
⑤ “deliver.test_queue"匹配消费指定队列的消息
此时需要我们切换guest用户添加trace
,选择虚拟主机“/
”:
账户:guest
密码:guest
添加成功后,我们在“queue”中会看到多一个队列:
说明: 在如上的测试trace(my_trace中设置了Pattern为#,可以记录所有信息)。
第一次进入需要输入账户密码(账户:guest,密码:guest):
注:
以上日志信息的显示中文乱码,暂时没有解决。
测试完毕,为不影响RabbitMQ性能(特别是生产环境),请关闭rabbitmq_tracing插件。
关闭插件命令:
[root@localhost ~]# rabbitmq-plugins disable rabbitmq_tracing
启动插件命令:
[root@localhost ~]# rabbitmq-plugins enable rabbitmq_tracing