当前位置: 首页 > 知识库问答 >
问题:

Spring AMQP惰性队列@RabbitListener并简化直接回复配置

东云
2023-03-14

目前,我有以下问题:外部RabbitMQ远程服务器需要我首先发送一条异步回复登录消息,然后发送一条广播队列broadcastQueue。MYUSER\u 123由此远程服务器创建。由此,我想通过@RabbitListener注释来使用,这在代码示例中可以看到。但我有一个错误,你可以看到下面。

在调试过程中,我注意到在我的代码中执行登录之前,容器启动了这个监听器,因此在连接这个广播队列时会遭到拒绝。我在如何使用@Lazy-in-spring-boot延迟加载RabbitMQ队列中找到了这篇文章?但我这边的问题是,autostart不起作用,并且为侦听器启动了容器。我做错了什么?是否可以创建惰性队列。?

另一点是:有没有一种简单的方法可以为RabbitMQ模板进行直接回复配置,我可以在其中指定回复地址?根据Spring amqp代码,似乎只有在您自己不指定回复地址的情况下才能进行直接回复连接。所以我需要创建一个自定义容器。

谢谢你的帮助。

问候斯文

@SpringBootTest
@Slf4j
class DemoAmqpApplicationTests {

    @RabbitListener(queues="broadcastQueue.MYUSER_123",autoStartup = "false")
    public void handleMessage(Object obj) {
        log.info("{}",obj);

    }

    @Test
    void contextLoads() throws InterruptedException {
        Message<User> login = login();
                

    }

配置

@Configuration
@Slf4j
@EnableRabbit
public class RabbitMqConfiguration {

    @Bean
    public RabbitAdmin amqpAdmin(RabbitTemplate rabbitTemplate) {
        return new RabbitAdmin(rabbitTemplate);
    }

    @Bean
    public RabbitTemplate rabbitTemplate(@NonNull CachingConnectionFactory connectionFactory,
                                         @NonNull MessageConverter messageConverter,
                                         @NonNull Queue inquiryResponseQueue,
                                         @NonNull RabbitTemplateConfigurer configurer) {

        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        configurer.configure(rabbitTemplate, connectionFactory);

        String username = connectionFactory.getUsername();

        configurePostReceiveProcessor(rabbitTemplate);

        rabbitTemplate.setMessageConverter(messageConverter);

        configurePrepareSendingProcessor(rabbitTemplate, username, inquiryResponseQueue.getName());

        configureReply(rabbitTemplate, inquiryResponseQueue);

        return rabbitTemplate;
    }

    private void configureReply(RabbitTemplate rabbitTemplate,
                             
                                @NonNull Queue inquiryResponseQueue) {
        rabbitTemplate.setReplyAddress(inquiryResponseQueue.getName());
        rabbitTemplate.setDefaultReceiveQueue(inquiryResponseQueue.getName());
    }

    @Bean
    public SimpleMessageListenerContainer replyListenerContainer(
            @NonNull CachingConnectionFactory connectionFactory,
            @NonNull List<Queue> inquiryResponseQueue,
            @NonNull RabbitTemplate rabbitTemplate,
            @NonNull RabbitAdmin rabbitAdmin) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueues(inquiryResponseQueue.get(0));
        container.setMessageListener(rabbitTemplate);
        return container;
    }

    @Bean
    public Queue privateInquiryResponseQueue(
            @NonNull CachingConnectionFactory connectionFactory) {
        return new Queue(privateInquiryResponseQueueName(connectionFactory.getUsername()),
                false,
                true,
                true);
    }

    

}

错误日志:

    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:721) ~[spring-rabbit-2.3.10.jar:2.3.10]
    ... 5 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'broadcastQueue.MYUSER_123' in vhost 'app', class-id=50, method-id=10)

共有1个答案

阙新觉
2023-03-14

autoStartup工作正常-必须有其他东西启动容器-添加断点以查看是什么启动它-是否在应用程序上下文上调用start()?这将启动容器。

直接回复是一种特殊的RabbitMQ模式,它使用伪队列进行回复;对于命名回复队列,需要一个侦听器容器。

https://docs.spring.io/spring-amqp/docs/current/reference/html/#direct-回复至

 类似资料:
  • 我已经通过应用程序配置了我的兔子属性。yaml和spring配置属性。因此,在配置交换、队列和绑定时,可以使用属性的getter 然而,当我配置@RabbitListener从队列登录消息时,我必须使用完整的属性名称,如 我希望避免这种容易出错的硬编码字符串,并参考configurationProperties bean,如: 我曾经遇到过一个与@EventListener类似的问题,在这里使用b

  • 主要内容:9. RabbitMQ 其他知识点,9.1 幂等性,9.2 优先级队列,9.3 惰性队列9. RabbitMQ 其他知识点 9.1 幂等性 9.1.1 概念 用户对于统一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生副作用 举个栗子,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,会进行第二次扣款,返回结果依然成功。用户查询余额发现多扣钱了,流水记录也变成了两条。 在以前的但应用系统中,我们只需要把数据操作放入事务

  • 一、 我与CachingConnectionFactory有一个SpringAMQP项目。我需要从AMQP连接获取一些属性,例如:状态、连接时间、通道和一些运行时度量。CachingConnectionFactory是否有任何指标支持(例如:https://www.rabbitmq.com/blog/2016/11/30/metrics-support-in-rabbitmq-java-clien

  • 我想知道,在Spring AMQP中,是否可以根据负载类型在多个类中接收来自同一队列的消息。 我知道在类中使用@RabbitListener注释,然后将@RabbitHandler放在方法上,但我希望在保持单个队列的同时将消息处理的复杂性拆分为多个类。 当前使用的版本:Spring AMQP v2.0.3以及RabbitMQ。

  • 下面是一个重现我的问题的示例项目:https://github.com/deathcoder/hazelcast-shared-session

  • 问题内容: 我有一个实体: 然后我有一个控制器,其目的是检索书籍,我的问题是,流派字段包含在控制器的json响应中。有什么办法可以排除杰克逊序列化对象时延迟加载的那些字段? 这是我的ObjectMapper的配置: 谢谢! 我无法将其标记为JsonIgnore,因为它将永远在序列化框中。有时候,我将需要随书一起检索体裁,到那时,我将在查询中使用“获取联接”,因此它不会为null。 问题答案: 你可