在Spring Stream应用程序中发生RabbitMQ通道关闭异常时需要监听器类

时间:2019-02-18 22:49:03

标签: spring rabbitmq spring-amqp spring-cloud-stream spring-cloud-dataflow

我们正在使用Spring Cloud数据流应用程序和RabbitMQ作为消息代理。

在从源模块到接收器模块的总体流中,只要看到给定流中的任何模块中发生“ ChannelShutdown:连接错误”,我们就会丢失数据。

Stream Example: Source | Transformer1 | transformer2 | transformer3 | sink

即任何RabbitMQ通道连接丢失,然后应用程序无法将数据传输到下一个模块/应用程序,从而导致数据丢失。

例外:

2019-02-18 15:29:41.364 ERROR 94489 --- [ 127.0.0.1:5672] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: connection error; 
2019-02-18 15:29:42.008  INFO 94489 --- [strationQueue-1] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer@6adc5b9c: tags=[{amq.ctag-5dNneAd3QgwWADta7JAmQQ=employeeRegistrations.employeeRegistrationQueue}], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,1), conn: Proxy@a6e4897 Shared Rabbit Connection: SimpleConnection@22dc59b2 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 50775], acknowledgeMode=NONE local queue size=0
2019-02-18 15:29:42.010  INFO 94489 --- [strationQueue-2] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [localhost:5672]
2019-02-18 15:29:42.019  INFO 94489 --- [strationQueue-2] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#d611f1c:1/SimpleConnection@1782b48a [delegate=amqp://guest@127.0.0.1:5672/, localPort= 50864]

要复制问题: 我运行了两个Spring Cloud Stream程序

  1. 生产者-将100,000条消息推送到RabbitMQ交换
  2. 消费者-接收器模块从该队列接收有效负载(链接到交换)并打印

为了在消费者程序日志中获得“通道关闭:连接错误”,我转到rabbitMQ UI页面并不断删除RabbitMQ UI页面中可用的连接。

enter image description here

最后,在此过程中,消费者在100,000条消息中仅收到98,484条消息。因此,由于通道连接关闭,我们在传输中丢失了数据


我的问题:

我们可以在Spring流应用程序中捕获或检测到“频道关闭:连接错误”吗?

流应用程序中是否可以包含任何RabbitMQ侦听器类来处理错误“通道关闭:连接错误”?

我遇到了像

这样的RabbitMQ听众

在Stream应用程序内部使用@RabbitListener注释

Example:
@RabbitListener(queues = TEST_QUEUE)
    public void handle(Foo in) {
        logger.info("Received: " + in);
    }

但是此RabbitMQ侦听器仅侦听定义https://docs.spring.io/spring-amqp/api/org/springframework/amqp/rabbit/annotation/RabbitListener.html中指定的指定队列或绑定

  

我想知道是否有任何常见的RabbitMQ侦听器类   收听频道连接,而不是收听特定频道   队列。

     

所以我的问题就像是否有任何监听器可用于检查任何   通道[链接到当前应用程序]是否关闭   所以我可以通过将有效载荷发送回下一个来处理数据丢失   建立通道连接后的应用程序。

在这种情况下 SimpleRabbitListenerContainerFactory类对我有帮助吗?如果是这样,请让我知道解决由于通道关闭和连接丢失问题而导致的数据丢失问题的方法。

示例:

1 个答案:

答案 0 :(得分:0)

您可以使用Spring Boot属性在生产者中启用重试。 Documentation here

向下滚动到RabbitMQ

...
spring.rabbitmq.template.retry.enabled=false # Whether publishing retries are enabled.
spring.rabbitmq.template.retry.initial-interval=1000ms # Duration between the first and second attempt to deliver a message.
spring.rabbitmq.template.retry.max-attempts=3 # Maximum number of attempts to deliver a message.
spring.rabbitmq.template.retry.max-interval=10000ms # Maximum duration between attempts.
spring.rabbitmq.template.retry.multiplier=1 # Multiplier to apply to the previous retry interval.
...

但是,要回答您的问题,可以在连接工厂bean定义中添加ConnectionListener