Question

J'ai une situation intéressante sur mes mains. Depuis quelques années, nous avons eu un service WCF qui fonctionne sur une boîte IIS sur notre réseau que nous utilisons pour la journalisation. Les applications utilisent BasichttpLinding pour envoyer des messages de journal et les enregistre dans une base de données. La plupart de la journalisation de toutes les autres applications se limitent à quelques douzaines de journaux par opération. Récemment, nous avons porté une autre application pour utiliser ce service de journalisation. Cette application se connecte un peu plus agressivement que l'un des autres clients de notre service de journalisation. Il dispose d'une opération qui au cours de son cours pourrait enregistrer plus de 100 000 messages (ceci pour importer 100 000 enregistrements via le fichier CSV).

En essayant de trouver un moyen de faire fonctionner plus efficacement, il a été suggéré d'essayer MSMQ à faire la queue des demandes de journal et de les transmettre au service au lieu de la communication directe avec le service de journalisation (la demande était étant envoyé dans un fil séparé à des fins de performance). De cette manière, l'application n'est pas bloquée pendant l'écriture du journal. J'ai mis en place une preuve de concept pour cette solution MSMQ sur ma machine locale, mais comme je n'ai jamais utilisé MSMQ auparavant, et comme je ne sais que maintenant ce que sa place est sur le plan technologique, je me trouve avec beaucoup de questions et quelques réponses . J'espère que quelqu'un peut me diriger certaines informations concises sur la manière dont MSMQ fonctionne afin de pouvoir mieux déboguer cette preuve de concept que j'ai écrit.

Qu'est-ce que je vois après la mise en œuvre MSMQ:

  • mon application qui envoie les journaux à MSMQ revient presque immédiatement (plutôt que d'attendre le journal être engagé) qui est ce que je veux.
  • même si j'ai envoyé 1000 journaux à la Application MSMQ dans moins de 30 ans secondes, il faut plusieurs minutes pour tous les 1000 journaux pour le faire à la base de données. Il semble que mon La file d'attente a une sorte de peuplement Activé où il retient le Demandes de journal mais je ne sais pas comment / où vérifier cela.
  • Si j'utilise net.tcp sur le serveur recevant les journaux du service MSMQ, je reçois une tonne d'erreurs de délai d'attente de service et seulement 90% (environ) des journaux le rend sur la base de données, mais si j'utilise BasichttpLinding ça marche fiable.

    Voici le code de mon service 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"));
    
    }
    

    Voici le code de moi créant le service 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();
    }
    

    Voici le code de l'application que j'utilise pour appeler le service 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)
    });
    

    J'apprécie toute aide que quelqu'un puisse fournir. Je suis un peu perdue exactement à quel ensemble de fonctionnalités est disponible pour moi à l'aide de MSMQ. J'ai fait 6 heures de recherche via Google. La plupart des documents que j'ai trouvés sont assez anciens (2007) et sont une lecture difficile. Peut-être s'attendent-ils à avoir un niveau de connaissances basé sur le sujet.

Était-ce utile?

La solution

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"
       />

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top