我创建了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