Multiple ServiceStack applications with one RabbitMQ server
I created 2 ServiceStack apps that run as windows services via TopShelf and use one RabbitMQ server. Unfortunately, when I run the second application, the following exception is thrown:
Exception in MQ Rabbit server: AMQP operation was aborted: AMQP close-reason initiated by Peer, code = 406, text = "PRECONDITION_FAILED - cannot update exchange" mx.servicestack.topic "in vhost '/' with different type, durability, internal or autodetection "
The startup code contains the following code:
Appendix 1
...
var rabbitMqServer = new RabbitMqServer();
rabbitMqServer.RegisterHandler<BusMessages.CrawlRequest>(
n =>
{
var request = n.GetBody();
this.Crawl(request);
return null;
});
rabbitMqServer.Start();
...
Appendix 2
...
var rabbitMqServer = new RabbitMqServer();
rabbitMqServer.RegisterHandler<SendMailRequest>(
message =>
{
SendMail(message.GetBody());
return null;
});
rabbitMqServer.Start();
...
The problem seems to be related to the name swap mx.servicestack.topic
, which is the default by ServiceStack. Does anyone know a solution to work around this or change the Exchange name so that I can use multiple (default) ServiceStack applications in conjunction with the same RabbitMQ server?
Update
As I studied it more deeply, it seemed like a bug in ServiceStack.RabbitMq v4.0.31 (used in Appendix 1). In this version, an exchange exchange is mx.servicestack.topic
added as an exchange type fanout
instead of an exchange type topic
. Application 2 used ServiceStack.RabbitMq v4.0.40, which tries to add / use exchange mx.servicestack.topic
as an exchange type topic
, as it should. Updating the ServiceStack to version 4.0.40 for Application 1 fixed this issue.
I prefer the segregation method for different applications, as Alain explains in his answer on StackOverflow question .
However, for different applications running on the same (small) client domain, it is very convenient to use a default exchange such as ServiceStack.
Last but not least, I found a dirty workaround to get App 2 running alongside App 1 without updating the ServiceStack of App 1. This is done by doing the following:
...
QueueNames.ExchangeTopic = "mx.App2.topic";
var rabbitMqServer = new RabbitMqServer();
...
source to share
You need multiple vhosts on RabbitMQ server to separate your ServiceStack applications.
Instead, amqp://localhost:5672
you can use amqp://localhost:5672/vhostname
when configuring RabbitMqServer as described here:
https://github.com/ServiceStack/ServiceStack/wiki/Rabbit-MQ
In a practical deployment, the RabbitMQ server will not be on localhost. I use this above as a short step from where you are currently using the built-in default, which amqp://localhost:5672
when called new RabbitMqServer()
.
Virtual hosts must be added to the RabbitMQ server ahead of time, and users must be created for them separately. They are actually separate AMQP servers with a common infrastructure.
You can add vhosts with rabbitmqctl like this
rabbitmqctl add-vhost vhostname
source to share