Domanda

Ho una situazione interessante sulle mie mani. Per alcuni anni ora abbiamo avuto un servizio WCF che funziona su una scatola IIS sulla nostra rete che usiamo per la registrazione. Le applicazioni utilizzano Basichttpninding per inviare messaggi di registro e li registra a un database. La maggior parte della registrazione da tutte le altre applicazioni è limitata a poche dozzine di registri per operazione. Recentemente abbiamo portato un'altra applicazione per utilizzare questo servizio di registrazione. Questa applicazione registra un po 'più aggressiva di qualsiasi altro client per il nostro servizio di registrazione. Ha un'operazione che durante il suo corso potrebbe accedere a 100.000 messaggi (questo è per l'importazione di 100.000 record tramite file CSV).

Nel tentativo di trovare un modo per rendere questa corsa in modo più efficiente è stato suggerito di provare MSMQ a codare le richieste di registro e inoltrarle al servizio invece di avere l'applicazione comunica direttamente con il servizio di registrazione (la richiesta Era viene inviato in un filo separato per scopi di performance). In questo modo l'applicazione non è bloccata mentre il registro è stato scritto. Ho implementato una prova del concetto per questa soluzione MSMQ sulla mia macchina locale, ma come non ho mai usato MSMQ prima, e come sto solo imparando che il suo posto è tecnologicamente, mi sto trovando con un sacco di domande e poche risposte . Sperando che qualcuno possa indicarmi in qualche informazione concisa su come funziona MSMQ in modo da poter fare un notevole debug di questa prova del concetto che ho scritto.

Che cosa sto vedendo dopo aver implementato MSMQ:

    .
  • La mia applicazione che invia i registri a MSMQ ritorna quasi immediatamente (piuttosto che aspettare il tronco a essere commesso) che è quello che voglio.
  • Anche se ho inviato 1000 log al Applicazione MSMQ in meno di 30 secondi, ci vogliono diversi minuti per Tutti i 1000 log per arrivare al Banca dati. Sembra come se il mio la coda ha una sorta di limitazione abilitato da dove è trattenere il Registra le richieste ma non so come / dove controllarlo.
  • Se utilizzo net.tcp sul server che riceve i registri dal servizio MSMQ ottenendo un sacco di errori di timeout del servizio e solo il 90% (o così) dei registri lo rendono al database ma se utilizzo basichttpbinding funziona in modo affidabile.

    Ecco il codice nel mio servizio 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"));
    
    }
    
    .

    Ecco il codice di me creando il servizio 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();
    }
    
    .

    Ecco il codice nell'applicazione che uso per chiamare il servizio 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)
    });
    
    .

    Apprezzo qualsiasi aiuto che qualcuno possa fornire. Sono un po 'perso esattamente su quale serie di funzionalità è disponibile per me usando MSMQ. Ho fatto 6 o così ore di ricerca tramite Google. La maggior parte dei documenti che ho trovato è piuttosto vecchio (2007) e sono una lettura dura. Forse mi aspettano che abbia qualche livello di basante di conoscenza sul soggetto.

È stato utile?

Soluzione

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top