为啥 Apache QPID 代理队列声明参数“x-qpid-dlq-enabled”不能正常工作?

Posted

技术标签:

【中文标题】为啥 Apache QPID 代理队列声明参数“x-qpid-dlq-enabled”不能正常工作?【英文标题】:Why does Apache QPID Broker queue declare argument "x-qpid-dlq-enabled" not function properly?为什么 Apache QPID 代理队列声明参数“x-qpid-dlq-enabled”不能正常工作? 【发布时间】:2020-04-11 08:08:19 【问题描述】:

我正在尝试将 Apache QPID 代理(版本 7.1.6)作为嵌入式内存代理运行,并在代理上声明一个队列,其中队列声明选项 x-qpid-dlq-enabled 设置为“true”。


public void createQueues() throws Exception 

    //connect to embedded broker running on local host
    ConnectionFactory factory = createConnectionFactory();
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();

    Map<String, Object> args = new HashMap<>();
    args.put("x-qpid-dlq-enabled",true);
    channel.queueDeclare("Test Queue", true, false, false, args);

根据此处找到的参数“x-qpid-dlq-enabled”条目:https://qpid.apache.org/releases/qpid-broker-j-7.1.0/book/Java-Broker-Appendix-Queue-Declare-Arguments.html

并根据此处第 9.4.3 节中描述的行为:https://qpid.apache.org/releases/qpid-java-6.1.0/java-broker/book/Java-Broker-Runtime-Handling-Undeliverable-Messages.html

如果使用该选项,预期的行为是会自动创建死信交换和死信队列。从上面的第二个链接:

“DLQ 功能导致生成死信交换和死信队列。它们的命名约定为 QueueName_DLE 和 QueueName_DLQ。

可以在创建新队列或使用队列声明属性 x-qpid-dlq-enabled 时启用 DLQ。"

但是,我在尝试使用该声明参数声明队列时收到以下错误。


    Exception in thread "main" java.io.IOException
        at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:129)
        at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:125)
        at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:147)
        at com.rabbitmq.client.impl.ChannelN.queueDeclare(ChannelN.java:968)
        at com.rabbitmq.client.impl.recovery.AutorecoveringChannel.queueDeclare(AutorecoveringChannel.java:333)
        at BrokerConnector.createQueues(BrokerConnector.java:43)
        at Main.main(Main.java:11)
    Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method: #method<connection.close>(reply-code=404, reply-text=Unknown alternate exchange: 'Test Queue_DLQ', class-id=50, method-id=10)
        at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)

我正在使用 RabbitMQ 客户端创建到 QPID 代理的 AMQPConnection,并且客户端和代理都使用 AMQ 协议 v 0_8。为什么没有按照 QPID 文档中的说明自动创建适当的交换,以及为什么交换名称后缀为“_DLQ”,而不是“_DLE”,正如文档中所指定的那样。我了解 Java 版本 6 的 Qpid 中记录了该行为,并且我正在运行版本 7.1.6,但后续文档中没有发布说明表明该行为应该有所不同,并且版本 7.1.6 文档仍然表明 "x-qpid-dlq-enable" 参数支持。

有什么建议或想法吗?

【问题讨论】:

【参考方案1】:

Qpid Broker J 的 7.0 版更改了配置死信队列的方式。不幸的是,看起来 v6 机制遗留了一些代码(和文档),这导致了您看到的错误。

从版本 7 开始,您可以直接在队列上设置 DLQ(或更准确地说是备用绑定),而无需备用交换。

如果您想自动完成,qpid-users@apache.org 邮件列表上的以下邮件交换可能会很有用:http://qpid.2158936.n2.nabble.com/Qpid-Broker-J-configure-alternate-binding-in-Node-auto-creation-policy-tp7684426.html

为我之前的(完全不正确的)猜测道歉 - 我承认部分代码不是我经常看到的。

【讨论】:

以上是关于为啥 Apache QPID 代理队列声明参数“x-qpid-dlq-enabled”不能正常工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 qpid-jms-client 创建 RabbitMQ 持久队列?

使用 Qpid 通过 SSL 与 AMQP 1.0 代理通信

Apache Qpid Python 1.35.0 发布

AMQP Qpid Proton - 无法将消息发送到超过 256 个队列

使用 AMQP 1.0 使用 Qpid 从客户端动态创建队列和主题

嵌入式代理假定 Logback 是 SL4J 绑定