带有一台RabbitMQ服务器的多个ServiceStack应用程序

我创建了2个ServiceTop应用程序,它们通过TopShelf作为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();
...

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

更新资料

当我更深入地研究它时,似乎是ServiceStack.RabbitMq v4.0.31(在App 1中使用)中的错误.在该版本中,默认交换mx.servicestack.topic被添加为扇出交换类型,而不是主题交换类型.应用程序2使用ServiceStack.RabbitMq v4.0.40,它试图添加/使用交换mx.servicestack.topic作为主题交换类型.将ServiceStack软件包升级到App 1的版本4.0.40可以解决此问题.

我喜欢针对不同应用程序的隔离方式,例如Alain在他的答案https://*.com/a/31209330/1278669中解释.
但是,对于在相同(小型)客户域中工作的不同应用程序,使用ServiceStack创建的默认交换是非常可行的.

最后但并非最不重要的一点是,我发现了一个肮脏的解决方法,可以在不升级App 1的ServiceStack软件包的情况下使App 2在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服务器将不在本地主机上.我将上述内容用作您从当前使用内置默认值的地方的一小步,该默认值是在调用新RabbitMqServer()时使用的默认值amqp:// localhost:5672.

需要提前在RabbitMQ服务器上添加虚拟主机,并且需要分别为其创建用户.它们实际上是具有共享基础结构的独立AMQP服务器.

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

rabbitmqctl add-vhost vhostname
上一篇:c#-什么是在Servicestack JsonServiceClient Get方法上实现重试的最佳解决方案?


下一篇:泛型对象转换为类型化对象