我手上有一个有趣的局面。几年来,我们已经在我们用于日志记录的网络上的IIS框上运行了一个WCF服务。应用程序使用basichttpbinding发送日志消息,它将它们记录到数据库中。所有其他应用程序的大多数日志记录都仅限于每次操作的几十个日志。最近,我们已将另一个应用程序移植以使用此日志期服务。此应用程序比我们的日志服务的任何其他客户端都更积极地日志。它有一个操作,在其课程中可以记录超过100,000条消息(这是通过CSV文件导入100,000条记录)。

在尝试找到一种方法来更有效地制作运行,建议我尝试使用msmq来队列日志请求并将它们转发到服务,而不是使用应用程序与日志服务通信(请求是在单独的线程中发送以进行性能目的)。通过这种方式,在编写日志时,应用程序不会被阻止。我已经在我的本地机器上实施了这个MSMQ解决方案的概念证据,但由于我以前从未使用过MSMQ,而且因为我现在只学习它的地方是技术的,我发现自己有很多问题和少数答案。我希望有人能指出一些关于MSMQ如何工作的简明信息,以便我能够更好地调试我写的概念证明。

实现MSMQ后我看到的内容:

  • 我的应用程序将日志发送到 MSMQ几乎立即返回 (而不是等待日志 致力于我想要的。
  • 即使我向其发送了1000个日志 MSMQ应用程序少于30 秒,需要几分钟 所有1000个日志都可以到 数据库。看起来好像我的 队列有某种节流 使能它拿回的地方 日志请求,但我不知道如何/在哪里检查。
  • 如果我在服务器上使用net.tcp从msmq服务接收日志,我会得到一大吨的服务超时错误,只有90%(左右)的日志使其到数据库,但如果我使用basichttpbinding它可以工作可靠地。

    以下是我的MSMQ服务中的代码:

    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"));
    
    }
    
    .

    这里是我的代码,创建MSMQ服务

    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();
    }
    
    .

    以下是我用来调用MSMQ服务的应用程序中的代码:

    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个或余的研究。我发现的大多数文档都是旧的(2007年)并且是一个艰难的阅读。也许他们期待我在主题上有一些基础知识水平。

有帮助吗?

解决方案

What you're seeing (if you're using net.msmq binding on your WCF) is what is designed to happen.

MSMQ, as a store-and-forward facility, will store messages in a queue at the sending client and the receiving server until either network or processing bandwidth is available. What this does is take load off the client (as you've observed) by making the process asynchronous.

You can view the statuses of the queues using Performance Monitor, the number of messages in the outbound queue (at the client) and the server queue are written to performance counters in realtime and can be viewed and/or logged.

If the performance is sub-optimal, you could look to change the WCF throttling settings to allow more concurrent connections in your service behaviour.

e.g.

<serviceThrottling
         maxConcurrentCalls="20"
         maxConcurrentSessions="20"
         maxConcurrentInstances="20"
       />

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top