多个 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
我已经通过 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