跳至主内容
版本:4.3

消费者取消通知

概述

当通道(channel)从队列进行消费时,可能会因为各种原因导致消费停止。显而易见的原因之一是客户端在同一通道上发出 basic.cancel 指令,这会导致消费者被取消,且服务器会回复一个 basic.cancel-ok。但其他事件,例如队列被删除,或者在集群场景下队列所在的节点发生故障,也会导致消费被取消,但客户端通道却无法获知这些情况,这通常很不方便。

为了解决这个问题,我们引入了一个扩展,当发生此类意外的消费者取消时,代理(broker)会向客户端发送一个 basic.cancel。如果是因为代理接收到来自客户端的 basic.cancel 而导致取消,则不会发送此通知。AMQP 0-9-1 客户端默认不会期望异步接收来自代理的 basic.cancel 方法,因此为了启用此行为,客户端必须在其 client-properties 中提供一个 capabilities 表,其中包含键 consumer_cancel_notify 和布尔值 true。详情请参阅关于功能(capabilities)的章节

我们支持的客户端默认会向代理声明此功能,因此代理会向其发送异步的 basic.cancel 方法,客户端随后将其呈现给消费者回调。例如,在我们的 Java 客户端中,Consumer 接口有一个 handleCancel 回调,可以通过继承 DefaultConsumer 类来重写它。

channel.queueDeclare(queue, false, true, false, null);
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleCancel(String consumerTag) throws IOException {
// consumer has been cancelled unexpectedly
}
};
channel.basicConsume(queue, consumer);

如果客户端对一个已意外取消(例如由于队列删除)的消费者发出 basic.cancel,这并不会报错。根据定义,客户端发出 basic.cancel 与代理发送异步通知之间可能存在竞态条件。在这种情况下,当代理收到 basic.cancel 时不会报错,并会像往常一样回复 basic.cancel-ok

消费者取消与复制队列

支持消费者取消通知的客户端在队列被删除或不可用时,总是会得到通知。消费者可以要求在复制队列的领导者(leader)发生变更时取消订阅。

© . This site is unofficial and not affiliated with VMware.