通过RabbitMQ / EasyNetQ发布并等待对某个主题的回应-如何只获取自己的主题?

时间:2019-01-29 08:32:44

标签: architecture rabbitmq easynetq

当发布者期望收到消息的答案时,如何确保在扩展消息时仅得到相关答案(针对其自身的消息)?

我们有一个客户端进程,该进程发布消息供服务器进程回答。此外,我们有一个“侦听器”过程,只需要消耗问题和答案,而无需发布任何内容。而且,将来服务器进程可能会分解为多个进程,从而创建消息级联。我们不能使用请求/响应,因为我们需要侦听器,然后再使用级联时,就需要使用侦听器...此外,我们将有几个问题/答案类别,并且EasyNetQ中的请求/响应不支持主题

我们使用EasyNetQ的解决方案是基于主题的简单发布/订阅:客户端发布到“ 问题”主题,订阅“ answer ”,服务器订阅“ 问题”并发布到“ 答案”,而侦听器只订阅这两者。

问题是当您扩展客户端时。它的两个实例现在都发布问题,但是由于它们都订阅了一个单独的“ 答案”主题,因此一个实例可能会得到另一个实例发布的问题的答案,而自己没有。< / p>

我们发现的解决方案是让客户在订阅“ 答案”时使用唯一命名的队列-这样,每个客户都将获得所有答案,而只需要忽略那些答案即可。不是他的。但是,此解决方案存在一些性能缺陷,并且还会导致每次客户端崩溃(或在开发过程中重新启动等)时,RabbitMQ中都会积累唯一命名的队列。

客户端,发送对象消息:

string corrId = Guid.NewGuid().ToString();

// Register the corrId in a dictionary
//...

var myMessage = new MyMessage {correlationId =corrId, realMessage = msg};
easyNetQBus.Subscribe<MyMessage>("mqClient"+uniqueSuffix, HandleMsg, x => x.WithTopic("answer"));
easyNetQBus.Publish(myMessage, "question");

// In HandleMsg, we see if we have issued questions with the correlation id that came with the answer (lookup in the dictionary) and if not, ignore it

服务器:

easyNetQBus.Subscribe<MyMessage>("mqServer", HandleMsg, x => x.WithTopic("question"));

// In HandleMsg, we publish the answer back to "answer" with the correlation id from the question

还有其他我们应该使用的模式吗?我们可以在每条消息中放入一个唯一的主题/队列来发送答案,但这使听众的生活以及我提到的级联中未来参与者的灵活性变得复杂起来。

0 个答案:

没有答案