众所周知,基于内容的路由是不受欢迎的。路由应该使用消息类型来完成。但是,您将如何解决服务器监听队列在欧盟分布的情况;美国地区,我们希望将这些信息传递给适当的地区。
这似乎是基于内容路由的经典场景:通过添加"区域"字段(如Enterprise Integration Pattern书中的小部件/小工具示例)
感谢
------------编辑2015年10月31日----------------
回复@mookid,关于rebus解决方案主张:
直到最近,我还认为命令是坏的("破坏体系结构|"),因为我认为发送到端点意味着特定的消费者(通过ip地址)。所以我更喜欢在所有事情上使用事件,这导致了如何解决区域问题的麻烦。
但现在我想一想,我可以使用IOrderPlaced接口,并为每条消息创建2个端点:IOrderPlaced_USA、IOrderPlaced_EU。端点的名称将放在app.config中,因此美国服务器将具有与欧盟服务器不同的app.config。
这将允许我在两个地区使用相同的RabbitMQ服务器,但不允许我从欧盟向美国发送消息——这可能是可以接受的我以上的理解正确吗?
我很难把所有的部分放在一起,你能谈谈你对你提出的解决方案的比较吗?
感谢
当您说"应该使用消息类型进行路由"时,这正是NServiceBus和其他.NET服务总线碰巧鼓励您使用的主要路由策略。
这种策略在许多情况下都能很好地工作,但在同样多的情况下,做你要求的事情也很好。
由于您已经用NServiceBus和MassTransit标记了这个问题,我想您还没有决定消息库——所以我冒昧地添加了Rebus标记,然后我可以向您展示如何使用Rebus进行基于内容的路由。
假设您想要发送一条DoSomething
消息,并且希望根据消息中的某个字段将其路由到两个不同的队列。实现这一目标的一种方法是
await bus.SendLocal(new DoSomething { Region = "US" });
它将消息发送到总线自己的输入队列,然后您就有了一个如下所示的处理程序:
public class DoSomethingForwarder : IHandleMessages<DoSomething>
{
readonly IBus bus;
public DoSomethingForwarder(IBus bus)
{
this.bus = bus;
}
public async Task Handle(DoSomething message)
{
var destination = DecideWhereToSend(message);
await bus.Advanced.TransportMessage.Forward(destination);
}
string DecideWhereToSend(DoSomething message)
{
//I'll leave the implementation to you :)
}
}
使用所述高级API将所述原始传输消息路由到另一目的地。
如果您想让路由器更快、更稳健地处理消息模式更改,您还可以通过路由配置API添加"传输消息转发器",根据头值路由消息。
不确定NServiceBus和MassTransit是如何做到这些的,但我相信他们可以用同样的方式做到。