不积跬步,无以至千里

RabbitMQ遇到的坑

1. NOT_ALLOWED - access to vhost '/' refused for user 'test'

https://blog.csdn.net/u010889616/article/details/80644225

定位发现是连接rabbitmq使用的用户没有赋予访问权限

rabbitmqctl.bat set_permissions -p / test '.*' '.*' '.*'

2. queue_declare 参数详解

  • queue_declare ()不带参数方法默认创建一个由RabbitMq命名的(amq.gen-LHQZz...)
    名称,这种队列也称之为匿名队列,排他 的,自动删除的,非持久化的队列
  • queue:队列名称
  • passive:如果用户仅仅想查询某一个队列是否已存在,如果不存在,不想建立该队列,仍然可以调用queue.declare,只不过需要将参数passive设为true,传给queue.declare,如果该队列已存在,则会返回true;如果不存在,则会返回Error,但是不会创建新的队列。
  • durable: 是不持久化, true ,表示持久化,会存盘,服务器重启仍然存在,false,非持久化
  • exclusive : 是否排他的,true,排他。如果一个队列声明为排他队列,该队列公对首次声明它的连接可见,并在连接断开时自动删除,
  • auto_delete :是否自动删除,true,自动删除,自动删除的前提:至少有一个消息者连接到这个队列,之后所有与这个队列连接的消息都断开时,才会自动删除,备注:生产者客户端创建这个队列,或者没有消息者客户端连接这个队列时,不会自动删除这个队列
  • arguments:其它一些参数。如:x-message-ttl,之类

https://www.jianshu.com/p/5634a9c71559
https://www.cnblogs.com/linkenpark/p/5393666.html

3. inequivalent arg 'durable' for exchange 'delay_exchange' in vhost '/': received 'false' but current is 'true'

 RabbitMQ 不允许你绑定一个非坚固(non-durable)的交换机和一个durable的队列。反之亦然。要想成功必须队列和交换机都是durable的。

一旦创建了队列和交换机,就不能修改其标志了。例如,如果创建了一个non-durable的队列,然后想把它改变成durable的,唯一的办法就是删除这个队列然后重现创建。因此,最好仔细检查创建的标志。

4. https://blog.csdn.net/wangzhan0123/article/details/80922327

1.normal_exchange_delay和normal_queue_delay是死信队列,设置了队列属性x-message-ttl的属性,即指定了延时时间,达到x-message-ttl设置的时间未消费的就会自动路由到normal_exchange_requeue交换器,从而实现了延迟重试。这里需要解释的是为什么要重新创建一个新的交换器normal_exchange_requeue:因为当你的normal_exchange绑定多个队列,且是topic类型的交换器时,如果你的死信队列指定的死信交换器是该交换器,消息存在发送到多个队列的风险,会对别的系统造成重复消费。

2.max retry如何获取,rabbitmq有一个属性,就是当一个消息进入到死信队列时,消费者收到的AMQP.BasicProperties参数中的headers属性中的cout参数就会加1,利用这个属性我们可以获取到该消息被消费了多少次。代码:

private function getRetryCount(AMQPMessage $msg): int
    {
        $retry = 0;
        Log::info('xx', [$msg->has('application_headers')]);
        if ($msg->has('application_headers')) {
            $headers = $msg->get('application_headers')->getNativeData();
            if (isset($headers['x-death'][0]['count'])) {
                $retry = $headers['x-death'][0]['count'];
            }
        }

        return (int)$retry;
    }

5. 声明队列报错:PhpAmqpLib\Exception\AMQPProtocolChannelException: PRECONDITION_FAILED - inequivalent arg 'x-message-ttl' for queue 'normal_queue' in vhost '/': received the value '30000' of type 'signedint' but current is none in file 。。。

 原因:queue已经存在,但是启动 consumer 时试图设定一个 x-dead-letter-exchange 参数,这和服务器上的定义不一样,server 不允许所以报错。如果删除 queue 重新 declare 则不会有问题。或者通过 policy 来设置这个参数也可以不用删除队列。也就是同时声明了2个属性不一致的队列
posted @ 2018-12-20 11:00  昃昃  阅读(22189)  评论(1编辑  收藏  举报
Just Do It !