2015-07-03 69 views
3

我创建了2个ServiceStack应用程序,它们通过TopShelf作为Windows服务运行,并使用一台RabbitMQ服务器。不幸的是,当我开始第二个应用程序会出现以下异常:带一台RabbitMQ服务器的多个ServiceStack应用程序

异常兔MQ服务器:AMQP操作被中断:AMQP近距离原因,通过同伴,代码= 406,文本=“PRECONDITION_FAILED启动 - 不能重新声明交换 '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软件包升级到App 1版本4.0.40解决了此问题。

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

最后但并非最不重要的,我发现了一个肮脏的解决方法,以获取应用2下一个运行到App 1而不升级这是通过以下操作完成的应用程序1的ServiceStack包:

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

回答

3

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

相反的amqp://localhost:5672你可以配置你的RabbitMqServer这里描述的时候使用amqp://localhost:5672/vhostnamehttps://github.com/ServiceStack/ServiceStack/wiki/Rabbit-MQ

在实际部署中的RabbitMQ服务器不会在本地主机上。我使用上面的内容作为从当前使用内置默认值amqp://localhost:5672调用new RabbitMqServer()的地方开始的一小步。

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

可以按如下

rabbitmqctl add-vhost vhostname 
+0

我会记住这为答案,因为这是隔离不同的应用程序的正确方法与rabbitmqctl添加虚拟主机。我还用更新部分编辑了我的问题,其中解释了我如何修复/防止发生的异常。 –

相关问题