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

本文关键字:一个 RabbitMQ 服务器 ServiceStack 应用程序 多个 | 更新日期: 2023-09-27 18:00:54

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

Rabbit MQ服务器中出现异常:AMQP操作中断:AMQP关闭原因,由Peer启动,代码=406,text="PRECONDITION_FAILED-无法重新声明vhost'/'中具有不同类型、持久、内部或自动删除值的exchange'mx.servicestack.topic'">

启动代码包含以下代码:

应用程序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(用于应用程序1(。在该版本中,默认交换机mx.servicestack.topic被添加为fanout交换机类型,而不是topic交换机类型。应用程序2正在使用ServiceStack。RabbitMq v4.0.40尝试添加/使用交换机mx.servicestack.topic作为topic交换类型,这是应该的。将ServiceStack包升级到应用程序1的4.0.40版本修复了此问题。

我更喜欢不同应用程序的隔离方式,就像阿兰在回答中解释的那样https://stackoverflow.com/a/31209330/1278669.
然而,对于在同一(小(客户域中工作的不同应用程序,使用ServiceStack创建的默认交换机是非常可行的。

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

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

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

RabbitMQ服务器中需要多个vhosts来隔离ServiceStack应用程序。

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

在实际部署中,RabbitMQ服务器不会在localhost上。在调用new RabbitMqServer()时,我将使用上面的内容作为当前使用内置默认值amqp://localhost:5672的一小步。

虚拟主机需要提前添加到RabbitMQ服务器上,并且需要为它们单独创建用户。它们是具有共享基础设施的有效分离的AMQP服务器。

您可以使用rabbitmqctl添加vhosts,如下所示

rabbitmqctl add-vhost vhostname