我是RabbitMQ的新手,从一个以相当老式的“RPC”模式使用RabbitMQ的项目开始。所以我在“服务器”方面尝试这样的事情:
ConnectionFactory factory = new ConnectionFactory();
factory.setUri(uri);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(queueName, false, false, false, null);
while (!shutdown) {
GetResponse gr = channel.basicGet(queueName, true);
... build reply ...
channel.basicPublish("", gr.getProps().getReplyTo(), replyProps, response);
}
我的问题是:在basicGet()上等待的线程是否可以被中断?如果是这样,会发生什么(未声明InterruptedException)。它意识到这不是一个很好的模式,但我只想要一些方法来干净地关闭服务。
更新:一条注释表明basicGet()根本没有阻塞,如果队列为空则立即返回。如果是这种情况,请允许我更准确地修改我的问题:如何等待队列中的消息并在超时时检索它?
UPDATE2:在rabbitmq邮件列表上进行实验和提问之后,我得出结论,这不能直接完成。它根本不是你在RabbitMQ中做事的方式。相反,您使用Channel.basicConsume()启动使用者线程池,并等待调用您的处理程序方法。它可以通过让你的消费者发布到SynchronizedQueue或类似的东西并让你的前台线程等待它来做间接,但要注意这会破坏basicConsume()提供的自动缩放和也使正确确认所有请求变得更加困难,并且还创建了额外的消息缓冲,这使得很难遵守basicQos()调用设置的QOS语义。
还应该注意的是,一旦你走下basicConsume()路线,消费者就可以被打断。这样就完成了:
// This starts a background thread pool
String consumerTag = channel.basicConsume(consumer);
...
// Shutdown the consumer thread pool
channel.basicCancel(consumerTag);
更新3:看到最后的答案。 RabbitMQ附带了一个非常出色的RpcClient类。
答案 0 :(得分:0)
basicGet
不会阻塞,它会立即返回(嗯,就在网络往返之后),如果队列中没有消息,则返回null。因此,不必中断线程。
答案 1 :(得分:0)
RabbitMQ Java API带有一个非常好的RPCClient实现,称为RPCClient(毫不奇怪)。用它!我做了一个example in github