多个 ServiceStack 应用程序与一个 RabbitMQ 服务器

Multiple ServiceStack applications with one RabbitMQ server

我已经通过 TopShelf 创建了 2 个 ServiceStack 应用程序 运行 作为 Windows 服务,并使用了一个 RabbitMQ 服务器。不幸的是,当我启动第二个应用程序时,发生以下异常:

Exception in Rabbit MQ Server: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text="PRECONDITION_FAILED - cannot redeclare exchange 'mx.servicestack.topic' in vhost '/' with different type, durable, internal or autodelete value"

启动代码包含以下代码:

应用 1

...
var rabbitMqServer = new RabbitMqServer();

rabbitMqServer.RegisterHandler<BusMessages.CrawlRequest>(
    n =>
    {
        var request = n.GetBody();
        this.Crawl(request);
        return null;
    });

rabbitMqServer.Start();
...

应用 2

...
var rabbitMqServer = new RabbitMqServer();

rabbitMqServer.RegisterHandler<SendMailRequest>(
    message =>
    {
        SendMail(message.GetBody());
        return null;
    });

rabbitMqServer.Start();
...

问题似乎出在名为 mx.servicestack.topic 的交换上,这是 ServiceStack 默认的。有谁知道绕过此问题或更改 Exchange 名称的解决方案,以便我可以将多个(而不是默认的)ServiceStack 应用程序与同一 RabbitMQ 服务器结合使用?

更新

当我更深入地研究它时,它似乎是 ServiceStack.RabbitMq v4.0.31(在 App 1 中使用)中的错误。在该版本中,默认交换 mx.servicestack.topic 被添加为 fanout 交换类型而不是 topic 交换类型。应用程序 2 使用 ServiceStack.RabbitMq v4.0.40 尝试 add/use 交换 mx.servicestack.topic 作为 topic 交换类型,因为它应该是。将 App 1 的 ServiceStack 包升级到版本 4.0.40 解决了这个问题。

我更喜欢像 Alain 在他的回答中解释的那样对不同应用程序进行隔离的方式
但是,对于在同一(小)客户域中工作的不同应用程序,使用 ServiceStack 创建的默认交换是非常可行的。

最后但同样重要的是,我发现了一个肮脏的解决方法,可以在不升级 App 1 的 ServiceStack 包的情况下将 App 2 运行ning 放在 App 1 旁边。这是通过执行以下操作完成的:

...
QueueNames.ExchangeTopic = "mx.App2.topic";
var rabbitMqServer = new RabbitMqServer();
...

您需要在 RabbitMQ 服务器中使用多个虚拟主机来隔离您的 ServiceStack 应用程序。

您可以在配置 RabbitMqServer 时使用 amqp://localhost:5672/vhostname 而不是 amqp://localhost:5672,如下所述: https://github.com/ServiceStack/ServiceStack/wiki/Rabbit-MQ

在实际部署中,RabbitMQ 服务器不会位于本地主机上。我在上面使用它作为调用 new RabbitMqServer().

时您当前使用内置默认值 amqp://localhost:5672 的一小步

需要提前在RabbitMQ服务器上添加虚拟主机,并单独为其创建用户。它们实际上是具有共享基础设施的独立 AMQP 服务器。

您可以使用 rabbitmqctl 添加虚拟主机,如下所示

rabbitmqctl add-vhost vhostname