使用Spring Cloud Stream的DLQ Rabbit错误绑定

时间:2019-05-29 16:47:04

标签: spring-boot spring-cloud-stream spring-rabbitmq

我有一个简单的Spring Cloud Stream应用程序,具有以下配置

spring:
    cloud:
        stream:
            rabbit:
                bindings:
                    input:
                        consumer:
                            exchangeType: topic
                            bindingRoutingKey: service.routing
                            autoBindDlq: true
                            deadLetterExchange: service.exchange.error
                            deadLetterQueueName: service.queue.error
                            deadLetterRoutingKey: service.routing.error
                            deadLetterExchangeType: topic
                            queueNameGroupOnly: true
                            republishToDlq: true
            bindings:
                input:
                    destination: service.exchange
                    group: service.queue
                    binder: rabbit
                    consumer:
                        errorChannelEnabled: true
                        maxAttempts: 2
                        concurrency: 3
            binders:
                rabbit:
                    type: rabbit
                    environment:
                        spring:
                            rabbitmq:
                                host: ${RABBITMQ_HOST:localhost}
                                port: ${RABBITMQ_PORT:5672}
                                username: ${RABBITMQ_USERNAME:guest}
                                password: ${RABBITMQ_PASSWORD:guest}

一切正常,但DLQ中的绑定不正确,因为DLQ没有收到任何消息。

预期结果

Exchange(service.exchange.error)-> 路由(service.routing.error)-> 队列(service.queue.error)

实际结果

交换(service.exchange.error)-> 路由(service.queue)-> 队列(service.queue.error)

反正有解决此问题的方法。

1 个答案:

答案 0 :(得分:0)

republishToDlq为true时,我们也绑定了队列名称,因为重新发布者对分区目标一无所知。

Binding dlqBinding = new Binding(dlq.getName(), DestinationType.QUEUE,
        dlxName, properties.getDlqDeadLetterRoutingKey() == null ? routingKey
                : properties.getDeadLetterRoutingKey(),
        null);
declareBinding(dlqName, dlqBinding);
if (properties instanceof RabbitConsumerProperties
        && ((RabbitConsumerProperties) properties).isRepublishToDlq()) {
    /*
     * Also bind with the base queue name when republishToDlq is used, which
     * does not know about partitioning
     */
    declareBinding(dlqName, new Binding(dlq.getName(), DestinationType.QUEUE,
            dlxName, baseQueueName, null));
}

所以您应该看到2个绑定-您的绑定和多余的一个。