java - 超时后收到回复

标签 java amqp spring-amqp

我想使用最新的 Spring 版本为 Spring AMQP 注册两个队列监听器:

    @Bean
    public SimpleMessageListenerContainer processingTransactionSaleContainer(ConnectionFactory cf, TransactionElavonSaleListener listener) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(cf);
        container.setQueueNames(QUEUE_PROCESSING_SALE);
        container.setMessageListener(new MessageListenerAdapter(listener, "transactionSaleProcess"));
        container.setMessageConverter(new SerializerMessageConverter());
        return container;
    }

    @Bean
    public SimpleMessageListenerContainer processingTransactionAuthorizeContainer(ConnectionFactory cf, TransactionAuthorizeListener listener) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(cf);
        container.setQueueNames(QUEUE_PROCESSING_AUTHORIZE);
        container.setMessageListener(new MessageListenerAdapter(listener, "transactionAuthorizeProcess"));
        container.setMessageConverter(new SerializerMessageConverter());
        return container;
    }

听众:

@Component
public class TransactionElavonSaleListener {

    public TransactionResponseFactory transactionElavonSaleProcess(TransactionRequestFactory ro) {
        ..... do some heavy network request
        return parseRawSuccessResponse(response);
    }

}

当我删除其中一个 SimpleMessageListenerContainer 时,它是工作文件,但是当我使用这两种方法时,我收到此异常:

00:40:14,469 INFO  [stdout] (pool-9-thread-5) 00:40:14.468 [pool-9-thread-5] WARN  o.s.amqp.rabbit.core.RabbitTemplate - Reply received after timeout for 1
00:40:14,472 INFO  [stdout] (pool-9-thread-5) 00:40:14.472 [pool-9-thread-5] WARN  o.s.a.r.l.ConditionalRejectingErrorHandler - Execution of Rabbit message listener failed.
00:40:14,473 INFO  [stdout] (pool-9-thread-5) org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
00:40:14,473 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1613)
00:40:14,473 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1517)
00:40:14,473 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1440)
00:40:14,473 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1428)
00:40:14,473 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1423)
00:40:14,473 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1372)
00:40:14,473 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.callExecuteListener(DirectMessageListenerContainer.java:995)
00:40:14,473 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.handleDelivery(DirectMessageListenerContainer.java:955)
00:40:14,474 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149)
00:40:14,474 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
00:40:14,474 INFO  [stdout] (pool-9-thread-5)   at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
00:40:14,474 INFO  [stdout] (pool-9-thread-5)   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
00:40:14,478 INFO  [stdout] (pool-9-thread-5)   at java.base/java.lang.Thread.run(Thread.java:844)
00:40:14,481 INFO  [stdout] (pool-9-thread-5) Caused by: org.springframework.amqp.AmqpRejectAndDontRequeueException: Reply received after timeout
00:40:14,494 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.core.RabbitTemplate.onMessage(RabbitTemplate.java:2446)
00:40:14,494 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.DirectReplyToMessageListenerContainer.lambda$setMessageListener$1(DirectReplyToMessageListenerContainer.java:115)
00:40:14,494 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1514)
00:40:14,494 INFO  [stdout] (pool-9-thread-5)   ... 11 common frames omitted
00:40:14,495 INFO  [stdout] (pool-9-thread-5) 00:40:14.495 [pool-9-thread-5] ERROR o.s.a.r.l.DirectReplyToMessageListenerContainer - Failed to invoke listener
00:40:14,495 INFO  [stdout] (pool-9-thread-5) org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
00:40:14,495 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1613)
00:40:14,495 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1517)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1440)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1428)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1423)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1372)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.callExecuteListener(DirectMessageListenerContainer.java:995)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.handleDelivery(DirectMessageListenerContainer.java:955)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
00:40:14,496 INFO  [stdout] (pool-9-thread-5)   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
00:40:14,497 INFO  [stdout] (pool-9-thread-5)   at java.base/java.lang.Thread.run(Thread.java:844)
00:40:14,497 INFO  [stdout] (pool-9-thread-5) Caused by: org.springframework.amqp.AmqpRejectAndDontRequeueException: Reply received after timeout
00:40:14,497 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.core.RabbitTemplate.onMessage(RabbitTemplate.java:2446)
00:40:14,497 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.DirectReplyToMessageListenerContainer.lambda$setMessageListener$1(DirectReplyToMessageListenerContainer.java:115)
00:40:14,497 INFO  [stdout] (pool-9-thread-5)   at deployment.rest_api.war//org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1514)
00:40:14,497 INFO  [stdout] (pool-9-thread-5)   ... 11 common frames omitted

你知道为什么当我有这两种方法时我会得到这个异常吗?

编辑定义的监听器:

    @Bean
    public SimpleMessageListenerContainer processingTransactionElavonSaleContainer(ConnectionFactory cf, TransactionElavonSaleListener listener) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(cf);
        container.setQueueNames(QUEUE_PROCESSING_ELAVON_SALE);
        container.setMessageListener(new MessageListenerAdapter(listener, "transactionElavonSaleProcess"));
        return container;
    }

    @Bean
    public SimpleMessageListenerContainer processingTransactionElavonAuthorizeContainer(ConnectionFactory cf, TransactionElavonAuthorizeListener listener) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(cf);
        container.setQueueNames(QUEUE_PROCESSING_ELAVON_AUTHORIZE);
        container.setMessageListener(new MessageListenerAdapter(listener, "transactionElavonAuthorizeProcess"));
        return container;
    }

...

@Component
public class TransactionElavonSaleListener {

    public TransactionResponseFactory transactionElavonSaleProcess(TransactionRequestFactory ro) {

        return new TransactionResponseFactory();
    }
}


@Component
public class TransactionElavonAuthorizeListener {

    public TransactionResponseFactory transactionElavonAuthorizeProcess(TransactionRequestFactory tf) {

        TransactionResponseFactory obj = new TransactionResponseFactory();                  
        return obj;
    }
}

发送对象:

TransactionResponseFactory processingPeply = (TransactionResponseFactory) processingTransactionElavonAuthorizeTemplate.convertSendAndReceive(
        ContextServer.EXCHANGE_PROCESSING, ContextServer.ROUTING_KEY_PROCESSING_TRANSACTION_ELAVON, tf);
    System.out.println("!!!!! Received PROCESSING_TRANSACTION " + processingPeply.getTransaction_id());

最佳答案

对您的配置的观察(但是与您的问题无关)...

  • AmqpAdmin 中的 declare... 代码不是必需的。
    • 您不应该在 Bean 定义阶段与代理交互 - 现在还为时过早。
    • 它们不是必需的,因为管理员会找到 QueueExchange bean,并在连接首次打开时自动为您声明它们。

是的,该消息转换器 setter 不用于这种监听器;消息转换器应该在 MessageListenerAdapter 上设置。

但是,它默认获得一个 SimpleMessageConverter,因此这不应该是问题;该转换器可以处理序列化对象以及纯文本。

现在,解决您的实际问题;添加第二个容器不应对客户端产生任何影响;每个模板都有自己的回复容器,并且默认使用直接回复,因此它们之间不会出现串扰(如果您使用命名回复队列,则可能会发生这种情况,但这里不是这种情况)。

我建议你打开DEBUG日志记录来弄清楚发生了什么;如果您需要帮助分析它们;发布日志(来自客户端和服务器端),我会看一下。

编辑

您的绑定(bind)不正确:

@Bean
public Binding bindingQueueProcessingElavonSale() {
    return BindingBuilder.bind(new Queue(QUEUE_PROCESSING_ELAVON_SALE, true))
            .to(new TopicExchange(EXCHANGE_PROCESSING)).with(ROUTING_KEY_PROCESSING_TRANSACTION_ELAVON);
}

@Bean
public Binding bindingQueueProcessingElavonAuthorize() {
    return BindingBuilder.bind(new Queue(QUEUE_PROCESSING_ELAVON_AUTHORIZE, true))
            .to(new TopicExchange(EXCHANGE_PROCESSING)).with(ROUTING_KEY_PROCESSING_TRANSACTION_ELAVON);
}

您使用相同的路由键将两个队列绑定(bind)到同一个交换器 - RabbitMQ 将使用该路由键向两个队列发送消息,因此两个监听器都会响应。

关于java - 超时后收到回复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54190371/

相关文章:

java - 使用不同名称创建对象

java - 仅包含图像的 ListView

java - basicAck 不会从代理中删除消息 - RabbitMQ

java - Spring消息TTL不起作用

java - Spring Boot 未连接到 RabbitMQ

java - 使用 Spring AMQP 监听许多短暂的、动态创建的队列

java - 类型为通用类型参数的 JAXB 编码字段

java - javafx中tableview中文本框的setgraphic后如何获取选定的行号和列号?

ruby - 如何使这个 AMQP 单消息订阅者稳定?

java - 验证 AMQConnection 连接字符串而不连接?