RabbitMq使用中常见错误小结

环境


分别使用了三个库使用RabbitMq。

  1. 使用python的pika库,适用于python。
  2. 使用rabbitmq-c库,-lrabbitmq,适用于c/c++语言。
  3. 使用AMQP-CPP库,-lamqpcpp,适用于c++。

主要对使用过程中出现的调试错误进行小结,适合新手参考。

pika库


  1. pika.exceptions.ProbableAuthenticationError: ConnectionClosedByBroker: (403) ‘ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.’
  • 登录信息不全,需要使用用户名和密码登录。或者用户名、密码不正确。

如,connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.1.2')),未使用用户名和密码等登录参数。可以参考下面的代码片段:

#!/usr/bin/env python
import pika

credentials = pika.PlainCredentials('the_user', 'the_pass')
parameters = pika.ConnectionParameters('132.45.23.14',
                                   5672,
                                   '/',
                                   credentials)

connection = pika.BlockingConnection(parameters)
  1. pika.exceptions.ProbableAccessDeniedError: StreamLostError: (“Stream connection lost: ConnectionResetError(10054, ‘远程主机强迫关闭了一个现有的连接。’, None, 10054, None)”,)
  • 服务未对该用户开放相关的权限,如 Virtual Host权限。需要登录服务端开放开头权限,以 Virtual Host权限为例:
    • 启动web管理服务:在安装目录执行:rabbitmq-plugins enable rabbitmq_management
    • 在浏览器中输入 http://127.0.0.1:15672,使用默认的用户名和密码登录:‘guest’, ‘guest’
    • 增加一个新用户
    • 点击用户名,点击开通权限即可
  1. pika.adapters.utils.connection_workflow.AMQPConnectorStackTimeout: Timeout during AMQP handshake’192.168.1.33’/(, , 6, ‘’, (‘192.168.1.33’, 15672)); ssl=False
  • 超时错误,可能是填写的端口号不正确
  1. pika.exceptions.ChannelClosedByBroker: (406, “PRECONDITION_FAILED - inequivalent arg ‘durable’ for exchange ‘CLP_STG’ in vhost ‘/’: received ‘false’ but current is ‘true’”)
  • 创建Exchange时,该Exchange已经存在,且本次创建时使用的参数与之前不符。具体到本异常,为 durable属性设置的值不同。
    • durable属性默认为false,无消息持久化特性
    • 创建Exchange时使用 durable=True设置为true,使用消息持久化特性

rabbitmq-c库


  1. open channel error: server channel error 406h, message: PRECONDITION_FAILED - unknown delivery tag 1
  • 消费者关闭了默认的ack机制,但仍然发送了ack,或者使用了ack,但发送ack时未使用与接收消息相同的通道
  1. 调用 amqp_channel_open 函数后,在管理界面查看通道已经打开,但该函数阻塞,一直未返回
  • 可能是在多线程中使用了同一个连接,或者多线程使用了同一个通道。在我的测试中,多线程使用同一个连接时,即使通道不同,也会出现该问题
  • 详情可以参考 amqp_channel_open issue

AMQP-CPP库


使用libevent事件驱动库。

  1. 执行了一系列创建工作,但在管理后台上查看时并未创建。
  • 所有的指令会在事件循环启动后执行,所以需要启动 event_base_dispatch(evbase);循环
  • 当持续有需要监听的事件时,该循环不会退出,所以不要在主进程中启动它,在线程中启动
  1. 如何注册事件回调函数
  • 所有的操作都是异步的,所以执行某指令后返回的值并不能判断该指令执行成功,需要注册回调函数,以及时处理错误
  • AMQP-CPP库内部使用的是类似 std::function形式的回调函数,在传入时使用 std::bind即可,参数使用占位符表示,如:
m_channel->publish(exchangeName, routingKey, msg)
            .onError(std::bind(&Foo::PublishMsgErrCb, this, std::placeholders::_1));
  1. 报错:UNEXPECTED_FRAME - expected content header for class 60, got non content header frame instead
  • 在功能测试通过的情况下,在压力测试下出现这个问题
  • 经过调试,是多个线程使用了同一个通道造成的问题。在RabbitMq中,connection是线程安全的,但channel不能多个线程共用一个。
  • 为不同的线程开启了不同的channel,问题解决

你可能感兴趣的:(工具使用)