spring amqp异步响应并将其与请求关联

时间:2018-07-02 11:54:31

标签: java spring rabbitmq spring-amqp

我正在尝试使用spring amqp实现请求-响应模式。
我看了看文档和示例,但是我仍然不明白如何使用关联ID 并在异步环境中为请求使用正确的响应。

假设我有一个 Transporter 类,该类接收请求,发送请求 到某些requestQueue,然后使用侦听器对某些responseQueue等待(阻塞)响应,然后返回响应。

现在,我有一个 AsyncSocketService ,它侦听requestQueue,然后通过套接字将请求发送到另一个处理请求并返回响应的服务器。该服务器异步工作,因此,如果有两个请求,则响应不必以相同的顺序进行。这意味着 AsyncSocketService 的响应是在另一个监听套接字 InputStream 的线程中管理的。

侦听套接字的 InputStream 的线程收到响应后,将其发布到responseQueue,然后侦听responseQueue的我的 Transporter 可以返回对原始呼叫者的响应。

运输工具像这样监听responseQueue:

byte[] response = (byte[]) rabbitTemplate.receiveAndConvert(queueName, timeout);

但是以这种方式,我不能确保给定的响应与正确的请求匹配。

当您定义带有回复地址的 SimpleMessageListenerContainer RabbitTemplate 时,我已经看到了一些使用回复队列的示例。 但我仍然不明白相关ID在哪里播放以及如何检查。而且此解决方案不适合我,因为我需要我的 Transporter 块并等待与请求匹配的响应。

重要的一点是,请求和响应在byte []中有一个refId字段,以允许请求和响应之间进行匹配,但是我不想捕获并重新排列不匹配的响应。

有人可以帮我找到用例的解决方案吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

您的体系结构还不清楚,恐怕无法直接回答您有关手动关联的问题,但是对于请求-答复情形,有RabbitTempalte.sendAndReceive()。如果确实需要,您可以使用固定的queue来配置它以进行答复:

/**
 * The name of the default queue to receive messages from when none is specified explicitly.
 *
 * @param queue the default queue name to use for receive
 */
public void setQueue(String queue) {

有一个自动关联支持,您可以通过以下方式进行控制:

/**
 * Set to true to use correlation id provided by the message instead of generating
 * the correlation id for request/reply scenarios. The correlation id must be unique
 * for all in-process requests to avoid cross talk.
 * <p>
 * <b>Users must therefore take create care to ensure uniqueness.</b>
 * @param userCorrelationId true to use user correlation data.
 */
public void setUserCorrelationId(boolean userCorrelationId)

同时,您需要将此RabbitTemplate配置为某些MessageListenerContainer的侦听器,才能真正使用这些异步回复。

对于真正的异步请求/答复,还有一个AsyncRabbitTemplate变体,它返回RabbitMessageFuture供以后使用答复。

无论如何,requestQueue消费者方支持将相关性转移回回复非常重要。否则,在生产者端将没有任何东西可以匹配已发送请求的异步回复。

所有信息都在Reference Manual中。