RabbitMQ Java API:我想使用basicGet()进行RPC调用。可以阻止吗?可以打断吗?

时间:2018-06-18 20:15:45

标签: rabbitmq

我是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类。

2 个答案:

答案 0 :(得分:0)

basicGet不会阻塞,它会立即返回(嗯,就在网络往返之后),如果队列中没有消息,则返回null。因此,不必中断线程。

答案 1 :(得分:0)

RabbitMQ Java API带有一个非常好的RPCClient实现,称为RPCClient(毫不奇怪)。用它!我做了一个example in github