NServiceBus.Unicast.Transport.CompletionMessage was not registered in the serializer - nservicebus

A suite of integration services that use NServiceBus have been dropped in my lap (unfortunately I was not involved in the original implementation and the person who did write the code has left).
The services work fine in our development & testing environments; but I cannot get them to run in our production environment. I get the error
NServiceBus.Unicast.Transport.CompletionMessage was not registered in the serializer.
Check that it appears in the list of configured assemblies/types to scan.
I've checked the config files on the servers and they're almost identical; in particular the MsmqTransportConfig and UnicastBusConfig blocks are identical. The major difference between the two environments is that in production, the web/app/database tiers are on separate servers whereas in the testing environment they all reside on the same server. However, the integration service calls are only made from the app tier, and even in production the app tier and integration services reside on the same server (at least for now), so I'm not sure this should make a difference.
I did download the documentation (the .chm file) but every topic I click on says "broken link".
I've also read several the questions and answers including this one, but since the code is working in our testing environment I'm somewhat reluctant to make changes to it.
We're configuring NServiceBus as follows:
NServiceBus.Configure.WithWeb()
.Log4Net()
.StructureMapBuilder(ObjectFactory.Container)
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.UnicastBus()
.LoadMessageHandlers()
.ImpersonateSender(false)
.CreateBus()
.Start();
and the transport is configured like so:
<MsmqTransportConfig
InputQueue="OutboundSubscriptionRequestQueue"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig
DistributorControlAddress=""
DistributorDataAddress=""
ForwardReceivedMessagesTo="">
<MessageEndpointMappings>
</MessageEndpointMappings>
</UnicastBusConfig>
I would really appreciate any assistance. I'm not necessarily looking to have an answer handed to me, just a nudge in the right direction ... right now I feel as though I'm shooting in the dark.

Sounds like nsb fails to scan nservicebus.core.dll for types. Can you verify that its present, not blocked and that log4net.dll is deployed in the same dir.

Related

Nservicebus disable default logger in web.config

I'm using the DefaultFactory LogManager for Nservicebus v5. I'm happy with this but was hoping to be able to disable via the web.config.
I use web.config settings, as found in the help docs
<configSections>
<section name="Logging" type="NServiceBus.Config.Logging, NServiceBus.Core" />
</configSections>
<Logging Threshold="Debug" />
I'd prefer not to set the threshold as fatal. I was hoping for a "None" or Disabled="true"
Also can the directory path be set web.config?
Update: Why would we want to ignore errors?
The short is we don't really have write permission on the servers.
The long is this isn't 100% true.
Our systems is moving towards microservices, the problem with this is that decentralized logging is a tracing/visualization nightmare.
So we moved flow tracing, exceptions, and limited tracing to a centralized system.
Programming Entry points (aka message Handlers, web api endpoints, etc) are nearly always wrapped in a try catch log throw on each handler, this covers all our programming errors. This isn't anything really that different to normal.
The centralized logging location sets of all the nice red flashing real time alarms one could wish for.
Which leaves only configuration type error left like missing queues, bad assembly bindings, faulty config files, or more runtime style stuff like IoC wiring (outside of the handler code).
With the centralized logging and monitoring of the error quests, it is fairly easy to detect when the service is broken and if it is then we turn on logging, restart, try the faulty issue, and fix.
Guaranteed delivery will take care of everything else once it is up again :D Gone are the days of 150mb log files spread across 10 different servers.
The simplicity of DefaultFactory was nice, as was not needing another nuget package and associated configuration.
Is this the correct way forward. Many would argue no.
Could we have done it better? yes we could implement the common logger interface and pass it into NServiceBus but we arn't quiet there just yet and the win isn't critical atm.
A side note: One really really nice thing about the way we log is that in our backoffice tool we have been able to simply show the flow for each "order", similar to using a correlation id in greylog.
Since this was not considered a likely scenario it does not have a first class API. But you can achieve this via passing in a null logger from any of the common logging libraries (NLog, Log4net, CommonLogging). I assume you are using one of these in your website.
So take NLog for example.
Install-Package NServiceBus.NLog
The in your webconfig
<appSettings>
<add key="disableLogging" value="true"/>
</appSettings>
Then in your global startup
if (ConfigurationManager.AppSettings.Get("disableLogging") == "true")
{
LoggingConfiguration config = new LoggingConfiguration();
LogManager.Configuration = config;
NServiceBus.Logging.LogManager.Use<NLogFactory>();
}
This is leveraging the approach documented here http://docs.particular.net/nservicebus/logging-in-nservicebus#nlog

NServiceBus 4.0.4 Subscriber very slow

I have a problem with my publish/subscribe implementation. I'm upgrading from NServiceBus version 2.6 to 4.0.4 and everything seems okay as far as I can understand from the logs but the messages are processed really slowly by the subscriber. I use NServiceBus.Host.exe.
In the old implementation I have configured threads as follows:
<MsmqTransportConfig
ErrorQueue="error"
NumberOfWorkerThreads="40"
MaxRetries="5" />
And the messages go through with nice speed.
In the new implementation I've tried to make the changes needed for the configurations:
<TransportConfig
MaximumConcurrencyLevel="10"
MaxRetries="5"
MaximumMessageThroughputPerSecond="500"/>
Am I missing something critical?
I have a valid license so I should have max threads in use. I haven't got RavenDB or SQL, the implementation uses MSMQ, I've disabled Sagas and TimeoutManager in my subscribers configuration code:
NServiceBus.SetLoggingLibrary.Log4Net(log4net.Config.XmlConfigurator.Configure);
Configure.Features.Disable<Sagas>();
NServiceBus.Configure.With()
.DefaultBuilder()
.UseTransport<Msmq>()
.DisableTimeoutManager()
.UnicastBus()
.LoadMessageHandlers();
I did a crude test and the difference in my development environment is so that the 2.6 version handled approximately 80 messages per second and the 4.0.4 version handled approximately 8 messages per second - which is really very bad. So something's wrong here and I just can't seem to find what it is.
Edit: It looks like the problem was generated from our project structure, for some reason the older version of NServiceBus didn't mind our structural approach with generic subsrcriber that uses MEF to load the actual subsrciber-assemblies but the new one went to sleep. I changed the folder structure and now the subscriber works as intended. So the configurations I was using work just fine, but I did delete MaximumMessageThroughputPerSecond from my settings so that it won't present a future problem since the aim is to be as fast as is possible.

How do I get my MVC application to send commands and subscribe to events in NServiceBus

Perhaps I'm missing something here and this question is maybe the same as this one so sorry for any duplication.
I have an MVC4 site that quite happily Sends() commands to my NServiceBus server. I now want the same MVC site to be able to subscribe to IEvents Publish()ed from the same NServiceBus server. But I just can't get it to work.
Messages are being published from the server and are showing in MSMQ but I can't get the MVC site to pick them up.
Is this possible with NServiceBus 3.3.5? And if so, how do I have to set up my MVC site to make it work?
Thanks in advance!
Edit: Here's the config I have in the MVC app:
Configure.With()
.Log4Net()
.StructureMapBuilder()
.MsmqTransport()
.IsTransactional(false)
.PurgeOnStartup(false)
.UnicastBus()
.LoadMessageHandlers()
.ImpersonateSender(false)
.JsonSerializer()
.CreateBus()
.Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
I don't have an EndpointConfig class that implements the IConfigureThisEndpoint or and AsA_ interfaces. I've tried adding one but it never gets called and I can't work out what the host would be or how to start the NServiceBus host application from the web app. Or even what context the host would run under if the code sits inside IIS (if that makes sense!).
My guess is you're missing the .LoadMessageHandlers() line in your fluent config after .UnicastBus() - that's the most common error that leads to self-hosted applications not processing messages sent to them.
If that's not the case, add your fluent config block to your question and we'll take a look.
Edit: After fluent config posted
My next guess is that you're declaring your serializer too late. The .UnicastBus() step is one of the last stops before "Let's start this thing!" I'm thinking perhaps by the time you've hit this point, the config has made the assumption you're going with the default XmlSerializer. Could you try moving the serializer line to right after .StructureMapBuilder() and see if that works better?
If that doesn't work I might consider using the .DefaultBuilder() momentarily just to rule out an problem with your IoC container.
In regards to your other comments, a self-hosted bus will never have an EndpointConfig. That's a pointer for endpoints hosted by the NServiceBus.Host.exe only.
I also suppose it's not completely obvious where you're calling this fluent config from. This code needs to be called once when the webapp is started up - usually from the application start method in the Global.asax. Because the webapp is in control, there's no automatic assembly scanning to find and wire up your NServiceBus pipeline like in the NServiceBus Host.

NServiceBus Loading All Assemblies Regardless of Setting

I am trying to run an NServiceBus solution containing several endpoint configs in one directory. I am executing the host.exe with (among other things) /endpointConfigurationType:"class, assembly".
The host correctly isolates itself to using only the one endpoint config, but then it appears to scan the directory anyway, loading and leveraging any NSB interfaces found in other DLLs that are used by the other services. For example, the IWantToRunAtStartup implementations in other endpoint DLLs are being executed even though I only expect NSB to care about interfaces found in /endpointConfigurationType.
What all steps are required to deploy an NSB solution to a flat folder structure, such that NSB will only concern itself with the endpoint it is told to execute?
See the "File Scanning" section of this page:
http://support.nservicebus.com/customer/portal/articles/856698-the-nservicebus-host
The following should work:
Configure.With(Assembly.GetExecutingAssembly())
.NinjectBuilder(kernel)
.FileShareDataBus(BasePath)
.UnicastBus()
.MsmqSubscriptionStorage()
.PurgeOnStartup(false)
.XmlSerializer()
.MsmqTransport();
Regarding the installation, just make sure you run /install for each /endpointConfigurationType, see http://support.nservicebus.com/customer/portal/articles/856698#installation

NServiceBus message handler not going to 'error' queue on exception

I have a sample NServiceBus application to test the waters.. All is going well, sending and handling is working correctly.
I have deliberately thrown an exception within a certain message handler to see what happens - but nothing does. The exception is logged correctly to the console, yet the message is pulled off the queue and NOT placed in the error queue as I'd expect. Also, the 5 times retry didn't occur either. Is this correct behaviour?
Also, the queue was created correctly at startup when first specified.
the config and bootstrap code for the server (where the handler resides are below)
config:
<MsmqTransportConfig
InputQueue="SiteServer1"
NumberOfWorkerThreads="1"
MaxRetries="5"
ErrorQueue="SiteServer1Errors"
/>
program.cs:
var bus = NServiceBus.Configure.With()
.Log4Net()
.CastleWindsorBuilder(container)
.XmlSerializer()
.MsmqTransport()
.UnicastBus()
.LoadMessageHandlers()
.CreateBus()
.Start();
Am I missing anything here?
I modified the bootstrapper code to include
.IsTransactional(true)
on the bus config and now it is working! It seems that non-transactional messages are disposable. Makes sense!
Are you running Windows Server 2008? If so you will find an event log in the event viewer, under the Application event logs -> windows -> MSMQ - End2End. This will record every action taken by the MSMQ subsystem on your machine.
I am guessing that NSB has tried to send the message to the error queue. However, what is really hapenning is that the MSMQ subsystem on your machine has consumed the message, but not been able to deliver it to the error queue for some reason.
I would look in the MSMQ log for an idea of what is going on.