当发布者期望得到消息的答案时,如何确保在扩展时它只能得到(与其自己的消息相关的)答案?
我们有一个客户端进程,它发布一条消息以供服务器进程应答。此外,我们有一个“监听器”进程,只需要消耗问题和答案,而不需要发布任何内容。此外,服务器进程将来可能会被分成多个进程,从而创建消息级联。我们不能使用请求/响应,因为我们需要监听器,然后,当我们需要级联时...此外,我们将有几个问题/答案类别,并且 EasyNetQ 中的请求/响应不支持主题。
我们使用 EasyNetQ 的解决方案是简单的基于主题的发布/订阅:客户端发布到“question“主题,订阅”answer”,服务器订阅“question”并发布到“answer”,听众只需订阅两者即可。
问题是当你扩展客户端时。它的两个实例现在发布问题,但由于它们都订阅了一个“answer”主题,一个人可能会得到另一个实例发布的问题的答案,而不是得到自己的答案。
我们找到的解决方案是让客户端在订阅“时使用唯一命名的队列”answer“ - 这样每个客户端都会得到所有的答案,只需要忽略不属于他的答案。但是,这个解决方案有一些性能缺陷,并且还会导致每次客户端崩溃(或只是在开发过程中重新启动等)。
客户端,发送对象消息:
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
Server:
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
我们还应该使用另一种模式吗?我们可以在每条消息中放入一个唯一的主题/队列来发送答案,但这使听众的生活变得复杂,也使我提到的级联中未来参与者的灵活性变得复杂......