I have an interesting situation on my hands. For several years now, we have a WCF service that runs in an IIS box on our network, which we use for logging. Applications use basicHttpBinding to send log messages and write them to the database. Most of the logs from all other applications are limited to a few dozen logs per operation. We recently ported another application to use this logging service. This application is quite aggressive than any other client for our logging service. It has an operation that during its course could record more than 100,000 messages (this is to import 100,000 records through a CSV file).
In an attempt to find a way to make this run more efficient, it was suggested that I try MSMQ to queue log requests and forward them to the service, instead of the application directly contacting the logging service (the request was sent to a separate thread to achieve goals). Thus, the application is not blocked during logging. I applied the proof of concept for this MSMQ solution on my local machine, but since I had never used MSMQ before, and since I am only now studying that its place is technologically, I am with a lot of questions and several answers, I hope someone can point me to a brief summary of how MSMQ works, so that I can better debug this proof of concept that I wrote.
What I see after implementing MSMQ:
- My application that sends logs to MSMQ returns almost immediately (instead of waiting for the log to be perfect), which is what I want.
- Although I sent 1000 logs to the MSMQ app in less than 30 seconds, it takes several minutes for all 1000 logs to reach the database. It seems that my turn has a kind of throttling enabled where it is holding back but I don't know how and where to check it.
- If I use net.tcp on a server that receives logs from the MSMQ service, I get a lot of service timeout errors, and only 90% (or so) of the logs do this in the database, but if I use basicHttpBinding, it works reliably .
Here is the code in my MSMQ service:
public void QueueLog(Log log)
{
try
{
ServiceClient writeLog = getLoggingService();
string exceptionText = log.Exception == null ? string.Empty : log.Exception.ToString();
writeLog.WriteCompatibleLog(log.LoggerName, (LoggingService.Logging.LogType)log.LogType, exceptionText, log.Message, log.ApplicationName, Utility.GetAssemblyVersion(Assembly.GetCallingAssembly()),
Utility.GetFirstIPAddress(), Utility.GetHostName(), log.Category);
}
catch (Exception ex)
{
Debug.WriteLine("LoggingServiceWrapper.DotNet Error\n\n" + ex.GetBaseException().Message + "\n\n" + ex.GetBaseException().StackTrace);
}
}
private ServiceClient getLoggingService()
{
return new ServiceClient(new BasicHttpBinding(), new EndpointAddress("http://MyServer/Service.svc"));
}
Here is the code me creating the MSMQ service
if (!MessageQueue.Exists(Properties.Settings.Default.QueueName))
{
MessageQueue.Create(Properties.Settings.Default.QueueName, true);
}
ServiceHost serviceHost = new ServiceHost(typeof(LoggingServiceQueue.LoggingServiceQueue), new Uri(Properties.Settings.Default.Address));
{
serviceHost.Open();
Console.ReadLine();
serviceHost.Close();
}
Here is the code in the application that I use to call the MSMQ service:
LoggingServiceQueueClient client = new LoggingServiceQueueClient(new NetMsmqBinding(NetMsmqSecurityMode.None), new EndpointAddress("net.msmq://localhost/private/Logging"));
client.QueueLog(new LoggingServiceQueue.Log
{
LoggerName = loggerName,
LogType = (LoggingServiceQueue.LogType)logType,
ApplicationName = applicationName,
Category = category,
Exception = exception,
Message = message,
SourceHostName = Utility.GetHostName(),
SourceIp = Utility.GetFirstIPAddress(),
Version = Utility.GetAssemblyVersion(callingAssembly)
});
, - . , MSMQ. 6 Google. , , (2007) . , , .