problems_rabbitmq

摘要:
RCA:之前消息确认改为了手动确认,如下设置:spring:rabbit:listener:direct:#manual消息手动确认;auto自动确认;none不确认acknowledge-mode:manualsimple:acknowledge-mode:manual所以需要在方法中显式调用确认方法,如下所示://第二个参数,手动确认可以被批处理,当该参数为true时,则可以一次性确认delivery_tag小于等于传入值的所有消息channel.basicAck;3springboot系统启动报错desc:报如下错误消息:2021-11-3009:53:55.321ERROR---org.springframework.amqp.rabbit.connection.CachingConnectionFactory.log[748]:ShutdownSignal:channelerror;protocolmethod:#methodRCA:设置了队列为durable和exclusive,系统重启后,队列还在,但是不能被重启系统后的新建的channel消费了,新建的channel属于另一个channel了。
目录
problems_rabbitmq

1 rabbitmq的guest账户无法远程登录,只能在本地登录

RCA: guest被限制为只能本地登录了,rabbitmq从3.3.0开始禁止使用guest/guest权限通过除localhost外的访问。

solution: 修改配置文件rabbit.app
(rabbit.app的路径,在我的ubuntu18.04系统中为:/usr/lib/rabbitmq/lib/rabbitmq_server-3.6.10/ebin/ )
将:{loopback_users, [<<"guest">>]},改为:{loopback_users, []}

reference: https://www.cnblogs.com/yzp666/archive/2019/06/11/11004975.html

2 每次启动系统,总是重复执行某个@RabbitListener监听的方法

desc: 每次启动总是执行那个方法,以下是方法中的提示消息:

2021-11-30 11:51:42.988  INFO --- com..orders.service.impl.BizOrderServiceImpl.notifyUserAfterOrderCreated[464]: 王五 您好,有笔订单支付提醒!订单编号:SN1000016,订单详情:http://url:port/vtbLhZ。订单有效期为半个小时,请在有效内尽快完成支付。感谢您的支持。

RCA: 之前消息确认改为了手动确认,如下设置:

spring:
  rabbit:
    listener:
      direct:
        # manual 消息手动确认;auto 自动确认;none 不确认
        acknowledge-mode: manual
      simple:
        acknowledge-mode: manual

所以需要在方法中显式调用确认方法,如下所示:

            // 第二个参数,手动确认可以被批处理,当该参数为 true 时,则可以一次性确认 delivery_tag 小于等于传入值的所有消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);

3 springboot系统启动报错

desc:报如下错误消息:

2021-11-30 09:53:55.321 ERROR --- org.springframework.amqp.rabbit.connection.CachingConnectionFactory.log[748]: Shutdown Signal: channel error; protocol method: #method<channel.close>(reply-code=405, reply-text=RESOURCE_LOCKED - cannot obtain exclusive access to locked queue 'biz.order.return.queue' in vhost '/'. It could be originally declared on another connection or the exclusive property value does not match that of the original declaration., class-id=50, method-id=10)

RCA: 设置了队列为durable和exclusive,系统重启后,队列还在,但是不能被重启系统后的新建的channel消费了,新建的channel属于另一个channel了。
那我怎么能消费原来的队列呢?

solution: 创建queue时,将exclusive属性设置为false,即“非独占”,允许其他的channel消费该队列。创建代码如下:

       /**
         * @param name 队列名称
         * @param durable 是否持久化,默认是true,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
         * @param exclusive 默认是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
         * @param autoDelete 是否自动删除, 默认false,当没有生产者或者消费者使用此队列,该队列会自动删除。
         */
        new Queue(BIZ_ORDER_SAVE_QUEUE, true, false, false);

4

Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [[B] to [com.beyondsoft.orders.entities.dto.BizOrderDTO] for GenericMessage [payload=byte[1554], headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedRoutingKey=biz.order.save.routingKey, spring_listener_return_correlation=adc96bdb-4283-4659-ac7f-31b37022bcfd, amqp_receivedExchange=biz.order.exchange, amqp_deliveryTag=1, amqp_consumerQueue=biz.order.save.queue, amqp_redelivered=false, id=f31ce1be-eaa9-59b3-65e7-18f35928e2d0, amqp_consumerTag=amq.ctag-6mIbvGvdRi8dsekH_xBudA, amqp_lastInBatch=false, contentType=application/x-java-serialized-object, timestamp=1638204199537}]

RCA: 没有配置消息转换器,没法转换原始的消息类型(好像是字节数组类型)为目标类型(即我们实际需要的类型)

solution: MyAMQPConfig类中,增加以下bean:

@Bean
public MessageConverter messageConverter() {
    return new Jackson2JsonMessageConverter();
}

5 springboot启动时rabbitmq总是报错

报错内容如下:

// 1 配置virtual-host为 / 时报如下错误:
Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method: #method<connection.close>(reply-code=530, reply-text=NOT_ALLOWED - access to vhost '/' refused for user 'java_demo', class-id=10, method-id=40)
RCA: 用户java_demo没有权限访问虚拟主机 /

// 2 配置virtual-host为 /java_demo 时报如下错误:
Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method: #method<connection.close>(reply-code=530, reply-text=NOT_ALLOWED - vhost /java_demo not found, class-id=10, method-id=40)
RCA:虚拟主机 /java_demo 不存在,此处因为前面多了一个斜杠,真正应该配置这个虚拟主机 java_demo
SOLUTION:然后我配置virtual-host为 java_demo,就能正常启动了。

// 3 在另一个springboot系统中,我配置 virtual-host 为 java_demo,但是总是报第1个错误:
Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method: #method<connection.close>(reply-code=530, reply-text=NOT_ALLOWED - access to vhost '/' refused for user 'java_demo', class-id=10, method-id=40)
ACTION:各种排查,各种修改配置文件,但仍然没用,而且可以确定配置文件的其他rabbitmq配置项是起作用的,就virtual-host不起作用,搞了几个小时。
RCA: 最终发现是在代码中写死了 virtual-host 为 / 
SOLUTION:将代码中的virtual-host改为使用配置文件中的值。
具体方法是:在RabbitMqConfig.java中增加私有属性:
    @Value("${spring.rabbitmq.virtual-host}")
    private String virtualHost;

    @Bean
    public ConnectionFactory connectionFactory() {
		...
        connectionFactory.setVirtualHost(virtualHost);
		...
	}

NOTE:
a. 配置文件中的配置为:
spring:
  rabbitmq:
    host: host1
    port: 5672
    username: username1
    password: password1
    virtual-host: java_demo
b. 代码中的写死的内容为:
类名:RabbitMqConfig.java
代码:
@Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host, port);
        connectionFactory.setUsername(userName);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost("/");
//        connectionFactory.setPublisherConfirms(true);
        return connectionFactory;
    }

6 rabbmitmq分布式事务总是不生效(待解决)

7

8

免责声明:文章转载自《problems_rabbitmq》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#判断ContextMenuStrip右键菜单的来源(从哪个控件弹出来的) (转载)如何判断一个 APP页面是否是H5页面下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

PHP处理kafka消息队列

在安装php-kafka 扩展后,就可以开始编写 php 消费消息的脚本了,php-rdkafka 扩展提供了几种消息处理的方式 低级方式(Low level) 这种方式没有消费组的概念 <?php $rk = newRdKafkaConsumer(); $rk->setLogLevel(LOG_DEBUG); //指定 broker 地...

使用NODEJS+REDIS开发一个消息队列以及定时任务处理

作者:RobanLee 原创文章,转载请注明: 萝卜李 http://www.robanlee.com 源码在这里: https://github.com/robanlee123/RobCron时间有限,就不详细注释,有问题或者意见欢迎@我,也欢迎大家批评指正. 本文所必须的一些资料如下: 1. NODEJS ==> 可以去NODEJS.ORG下载...

十二、消息驱动(SpringCloud Stream)

https://spring.io/projects/spring-cloud-stream#overviewhttps://cloud.spring.io/spring-cloud-static/spring-cloud-stream/3.0.1.RELEASE/reference/html/ 一、消息驱动概述   官网定义Spring Cloud St...

Freertos学习:07-队列

--- title: rtos-freertos-07-队列 EntryName : rtos-freertos-07 date: 2020-06-23 09:43:28 categories: tags: - ipc - queue - freertos --- 章节概述: 介绍 FreeRTOS中的任务间通讯机制:队列的使用(尽管FreeRTOS中没有...

C#利用RabbitMQ实现点对点消息传输

RabbitMQ做为消息代理,负责接收和转发消息,可以将RabbitMQ比喻为一个邮筒、一个邮局和一个邮递员。本文主要以一个简单的小例子,简述RabbitMQ实现消息传输的相关内容,仅供学习分享使用,如有不足之处,还请指正。 消息队列模型 所有 MQ 产品从模型抽象上来说都是一样的过程:消费者(consumer)订阅某个队列。生产者(producer)创建...

RabbitMQ安装配置

一、安装Erlang 1. 下载rpm包 wget https://bintray.com/rabbitmq/rpm/download_file?file_path=erlang%2F20%2Fel%2F7%2Fx86_64%2Ferlang-20.3-1.el7.centos.x86_64.rpm 2. 安装软件包 yum install downlo...