We have a fair number of services which we've already developed with NServiceBus, and we're just in the process of switching from using the MSMQ transport to using SQL Server transport.
For the NSB Hosted services, this has been relatively straightforward. But we're having an issue with setting up some of our websites (asp.net web api).
We're self-hosting within the websites, with the following configuration:
NServiceBus.Configure.Serialization.Xml();
var bus = NServiceBus.Configure.With(/* specific assemblies */)
.CastleWindsorBuilder(container)
.DefineEndpointName(
ConfigurationManager.AppSettings["nsb:EndpointName"])
.DefiningCommandsAs(t =>
t.GetCustomAttributes(typeof(/* our marker */), false)
.GetLength(0) > 0)
.DefiningEventsAs(t =>
t.GetCustomAttributes(typeof(/* our marker */), false)
.GetLength(0) > 0)
.SetEndpointSLA(new TimeSpan(0,10,0))
.UseNHibernateTimeoutPersister()
.UseNHibernateSubscriptionPersister()
.UseTransport<SqlServer>() //<-- Changed here
.UnicastBus()
.LoadMessageHandlers()
//.DoNotCreateQueues() //We create queues manually.
.CreateBus()
;
The only lines I've changed are the UseTransport<>
line (which previously had Msmq
), and, temporarily, the .DoNotCreateQueues()
line because I wanted to force it to create the queue tables (whilst I'm running locally under IIS express)
The issue is, when it creates the queue tables, it's appending my machine name onto the name of the "base" table. I.e. the tables it creates (when the EndpointName
app setting is Service.Name
) are of the form:
Service.Name.MYMACHINENAME
Service.Name.Retries
Service.Name.Timeouts
Service.Name.TimeoutsDispatcher
Whereas when it creates MSMQ queues, it creates:
Service.Name
Service.Name.Retries
Service.Name.Timeouts
Service.Name.TimeoutsDispatcher
And, indeed, Subscribers that have already been updated to the SQL Server transport are looking for the Service.Name
queue table to register their subscriptions.
What am I doing wrong or what other information is required to work this out?
I posted this exact question on the particular.net google group. This is the explanation I got from John Simons:
The reason why is because NServiceBus callbacks are correlated using an in-memory dictionary that keeps track of messages ids going out and messages ids coming in, so in other words when you do Bus.Send().Register(/* callback here */) in your web site we add an item to this in-memory dictionary saying that we sent out a message with id x and we also store the callback delegate and then when we receive messages we check that dictionary and if the correlation message id matches we fire the callback delegate.
So this means that if you scale out your web site (eg a web farm) where you deploy the same endpoint to multiple machines if the primary queue name for these endpoints were named the same any of these scaled out endpoints could pick up messages that are suppose to go to a specific endpoint/machine, which then would fail because the callback message would not exit in the in-memory dictionary for that endpoint/machine.
Full thread is here:
https://groups.google.com/d/msg/particularsoftware/W1RkPH6CBng/Ehiz0SPxKwoJ