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.
Related
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
I can't seem to get the Castle Windsor Integration working for Mass Transit over RabbitMQ. Everything was working fine until I introduced Windsor into the picture. I referenced Castle.Windsor 3.2 and MassTransit.WindsorIntegration 2.9 and configured the container for use within my application. I'm registering the MassTransit Consumers via:
Container.Register(..., Types.FromThisAssembly().BasedOn<IConsumer>());
When I debug and inspect the container after this line is ran, I can see that it successfully registered all of the consumers along with all of my other components. I then have the following code to initialize and register the service bus:
var serviceBus = ServiceBusFactory.New(sbc =>
{
sbc.UseRabbitMq();
sbc.ReceiveFrom(Config.ServiceBusEndpoint);
sbc.Subscribe(sc => sc.LoadFrom(Container));
});
Container.Register(Component.For<IServiceBus>().Instance(serviceBus));
I am using the LoadFrom(IWindsorContainer container) extension method provided by MassTransit.WindsorIntegration.
All of the examples I've found so far stop here and indicate that this is all you should have to do. Unfortunately for me my Consumers are never being called and messages are just piling up in the queue (eventually timing out and going to error queue). The fact that messages are showing up in the Consumer queue at all (+ I see a single consumer bound to the queue via the RabbitMQ Admin Tool) indicates to me that the consumers are probably being subscribed properly - so I'm not sure where the problem lies.
I added NLog logging for Windsor and MassTransit but no errors are showing up in the logs. I'm not sure how I should proceed troubleshooting at this point. Any ideas?
Also, this application is currently just a console application using Topshelf for development. Ultimately it will be installed as a Windows Service. Not sure if that is relevant or not but I thought I'd mention it just in case.
UPDATE
As a test I created a very simple Consumer with a parameter-less constructor for processing a very simple test message. This Consumer is successfully called! The "real" Consumers however have dependencies that need to be injected into them via the constructor. I was hoping the Container would resolve these but apparently it's having some sort of trouble. Weird that nothing is showing up in the logs about it. Stay tuned...
Okay I figured it out. Somewhere along the way when I was adding/removing NuGet packages I somehow managed to delete a reference to a DLL (ServiceStack.Text.dll) that one of my components needed (RedisClientsManager).
I started the debugger, let all my components get registered then popped open the Immediate Window and attempted to resolve each component one by one (by calling container.Resolve<RegisteredType>()) until I found the one that threw the exception when I attempted to resolve it.
The Exception message from Windsor at that point told me exactly what the problem was. I'm a little lost as to why this wasn't being logged or why the Exception was not raised when the container itself attempted to resolve it. Anyhow, moral of the story is make sure your components resolve.
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
I'm trying to set up the following broker using JDBC persistence:
<amq:broker id="activeMQBroker" brokerName="activeMQBroker" useJmx="false" persistent="true">
<amq:transportConnectors>
<amq:transportConnector name="vm" uri="vm://activeMQBroker" />
</amq:transportConnectors>
<amq:persistenceAdapter>
<amq:jdbcPersistenceAdapter dataSource="#dataSource" />
</amq:persistenceAdapter>
</amq:broker>
On startup, I get:
java.lang.NoClassDefFoundError: org/apache/kahadb/page/Transaction$Closure
If I add the KahaDB JAR to the classpath, all is well and the ActiveMQ database tables get created (in Postgres). I'd rather not have this additional dependency, though, since I'm not using it.
Any idea why ActiveMQ is still looking for KahaDB, even though I'm using JDBC? I tried setting schedulerSupport="false", as described in this question, but no luck.
P.S. Could someone with enough rep please create a "KahaDB" tag?
Current versions of ActiveMQ are tied pretty hard to KahaDB. The TempStore uses a paged list that uses KahaDB underneath as well. Its simplest to just include the library.
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.