RabbitMQ Java 客户端使用 DefaultConsumer 与 QueueingConsumer [英] RabbitMQ Java Client Using DefaultConsumer vs QueueingConsumer
问题描述
默认消费者
我的 DemoConsumer 继承自 DefaultConsumer.
我注意到以这种方式工作 handleDelivery() 是从 ThreadPool 调用的.
(打印 Thread.currentThread().getName() 我每次都看到 pool-1-thread-1/2/3/4.
我也测试了几次,看到订单保存了.
只是为了确保——因为不同的线程调用句柄传递——它会弄乱我的订单吗?
DefaultConsumer
My DemoConsumer inherits from DefaultConsumer.
I have noticed that working this way handleDelivery() is invoked from ThreadPool.
(printing Thread.currentThread().getName() I see pool-1-thread-1/2/3/4 eachtime.
I have also tested it several times and saw that the order is saved.
Just to make sure - since different threads call handle delivery - will it mess my order?
队列消费者
所有java教程都使用QueueingConsumer来消费消息.
在 API 文档中,它被称为已弃用的类.
我应该更改我的代码以从 DefaultConsumer 继承使用它吗?教程过时了吗?
QueueingConsumer
All of the java tutorial use QueueingConsumer to consume messages.
In the API Docs it is mentioned as a deprecated class.
Should I change my code to inherit from DefaultConsumer use it? Is the tutorial outdated?
谢谢.
推荐答案
是的,DefaultConsumer
使用可以更改的内部线程池.使用 ExecutorService
作为:
Yes,DefaultConsumer
uses an internal thread pool that can be changed.
Using ExecutorService
as:
ExecutorService es = Executors.newFixedThreadPool(20);
Connection conn = factory.newConnection(es);
阅读http://www.rabbitmq.com/api-guide.html 高级连接选项".
Read http://www.rabbitmq.com/api-guide.html "Advanced Connection options".
你可以从QueueingConsumer"中读到 doc:
As you can read from the "QueueingConsumer" doc:
因此,现在直接实现 Consumer 或扩展 DefaultConsumer 是安全的.
As such, it is now safe to implement Consumer directly or to extend DefaultConsumer.
我从未使用过 QueueingConsumer,因为它不是正确的事件驱动的.
I never used QueueingConsumer, because it isn’t properly event-driven.
如您所见:
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
/// here you are blocked, waiting the next message.
String message = new String(delivery.getBody());
}
这种情况下的一个典型问题是如何关闭订阅,一个常见的解决方法是在本地主机中发送一个标记的关闭消息.其实我不是很喜欢.
A typical problem in this case is how to close the subscription, and a common workaround is to send a tagged close message in local host. Actually I don’t like it so much.
如果你改为扩展DefaultConsumer
,你可以正确关闭订阅和频道:
If you extend DefaultConsumer
instead, you can correctly close the subscription and the channel:
public class MyConsumer extends DefaultConsumer {...}
然后
public static void main(String[] args) {
MyConsumer consumer = new MyConsumer (channel);
String consumerTag = channel.basicConsume(Constants.queue, false, consumer);
System.out.println("press any key to terminate");
System.in.read();
channel.basicCancel(consumerTag);
channel.close();
....
总而言之,您不必担心消息顺序,因为如果一切正常,则消息顺序是正确的,但我认为您不能假设它,因为如果出现问题,您可能会丢失消息顺序.如果你绝对需要维护消息顺序,你应该包含一个顺序标签来重构消费者端的消息顺序.
In conclusion, you shouldn’t worry about the message order because if all works correctly, the message order is correct, but I think you can’t assume it because if there is some problem, you can lose the message order. If you absolutely need to maintain message order, you should include a sequential tag to reconstruct the message order at the consumer side.
你应该扩展 DefaultConsumer.
And you should extend DefaultConsumer.
这篇关于RabbitMQ Java 客户端使用 DefaultConsumer 与 QueueingConsumer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!