Frage

Ich habe einen WCF-Dienst erstellen und bin unter Verwendung NetMsmqBinding Bindung.

Dies ist ein einfacher Service, der eine Dto meiner Service-Methode geht und erwartet keine Antwort. Die Nachricht wird in einem MSMQ gelegt und einmal in eine Datenbank eingefügt aufgenommen.

Was ist die beste Methode, um sicherzustellen, dass keine Daten verloren gehen werden.

Ich habe die 2 folgenden Methoden versucht:

  1. Werfen Sie eine Ausnahme

    Dies legt die Nachricht in einer Warteschlange für unzustellbare für die manuelle Prüfung. Ich kann diese verarbeiten, wenn mein strvice startet

  2. gesetzt die receiveRetryCount = "3" auf der Bindung

    Nach 3 Versuchen - die instantanously passieren, scheint dies die Nachricht in der Warteschlange zu verlassen, aber meinen Service bemängelt. Neustarten meinen Dienst wiederholt diesen Vorgang.

Im Idealfall würde Ich mag die Folge tun:

Versuche Prozess der Meldung

  • Wenn dies nicht gelingt, 5 Minuten warten für diese Nachricht und versuchen Sie es erneut.
  • Wenn das Verfahren 3 mal ausfällt, die Nachricht an eine Warteschlange für unzustellbare bewegen.
  • Ein Neustart des Dienstes werden alle Meldungen aus der Warteschlange für unzustellbare zurück in die Warteschlange schieben, so dass es bearbeitet werden.

Kann ich das erreichen? Wenn das so ist, wie? Können Sie mich zu jedem guten Artikel zu zeigen, wie man am besten WCF und MSMQ für meine gegebene Sceneria zu nutzen.

Jede Hilfe wäre sehr geschätzt. Dank!

Einige zusätzliche Informationen

Ich bin mit MSMQ 3.0 unter Windows XP und Windows Server 2003. Leider kann ich nicht bei MSMQ gezielt in Gift Nachricht Unterstützung gebaut 4.0 verwenden und Vista / 2008.

War es hilfreich?

Lösung

Es gibt eine Probe in dem SDK, das in Ihrem Fall nützlich sein könnte. Im Grunde, was es tut, ist eine IErrorHandler Implementierung zu Ihrem Dienst anhängen, die den Fehler fangen, wenn WCF die Nachricht erklärt, „Gift“ zu sein (das heißt, wenn alle konfigurierten Wiederholungen erschöpft sind). Was die Stichprobe ist die Nachricht an eine andere Warteschlange verschieben und starten Sie den Servicehost mit der Nachricht verknüpft (da es bemängelt haben, wenn das Gift Nachricht gefunden wurde).

Es ist nicht eine sehr hübsche Probe, aber es kann nützlich sein. Es gibt ein paar Einschränkungen, aber:

1- Wenn Sie mehrere Endpunkte haben im Zusammenhang mit Ihrem Service (dh durch mehrere Warteschlangen ausgesetzt ist), gibt es keine Möglichkeit, die das Gift Nachricht Warteschlange zu wissen, kam in. Wenn Sie nur eine einzige Warteschlange haben, wird dies kein Problem sein, . Ich habe keine offizielle Abhilfe für diesen gesehen, aber ich habe mit einer möglichen Alternative experimentiert, die ich hier dokumentiert: http://winterdom.com/weblog/2008/05/27/NetMSMQAndPoisonMessages.aspx

2- Sobald das Problem Nachricht an eine andere Warteschlange bewegt wird, wird es in Ihrer Verantwortung, so ist es an Ihnen, es zurück in die Verarbeitungswarteschlange zu bewegen, sobald das Timeout erfolgt (oder einen neuen Dienst zu dieser Warteschlange hängen Sie es zu handhaben ).

Um ehrlich zu sein, in jedem Fall sind Sie bei einigen „Handbuch“ Arbeit suchen hier, dass WCF gerade umfaßt nicht auf seine eigene.

Ich habe auf einem anderes Projekt vor kurzem arbeiten, wo ich eine Anforderung muß explizit steuern, wie oft Wiederholungen geschehen, und meine aktuelle Lösung war eine Reihe von Wiederholungs Warteschlangen zu erstellen und manuell Nachrichten zwischen den Wiederholungswarteschlangen und der Hauptverarbeitung bewegen Warteschlange basierend auf einer Reihe von Zeiten und einigen Heuristiken, nur die rohen System.Messaging Sachen mit den MSMQ-Warteschlangen zu behandeln. Es scheint ziemlich gut zu funktionieren, obwohl es ein paar Fallstricke ist, wenn Sie diesen Weg gehen.

Andere Tipps

Ich denke, mit MSMQ (verfügbar nur auf Vista) Sie könnten in der Lage sein, wie dies zu tun:

<bindings>
    <netMsmqBinding>
        <binding name="PosionMessageHandling"
             receiveRetryCount="3"
             retryCycleDelay="00:05:00"
             maxRetryCycles="3"
             receiveErrorHandling="Move" />
    </netMsmqBinding>
</bindings>

WCF wird sofort für ReceiveRetryCount mal nach dem ersten Anruffehler wiederholen. Nachdem die Charge fehlgeschlagen wird die Nachricht bewegt zu der Wiederholungswarteschlange. Nach einer Verzögerung von RetryCycleDelay Minute, bewegte die Nachricht aus der Wiederholungswarteschlange an die Endpunkt-Warteschlange und der Ansatz erneut versucht wird. Dies wird wiederholt MaxRetryCycle Zeit. Wenn alles, was die Meldung nicht entsprechend receiveErrorHandling behandelt die Bewegung sein kann (Zu vergiften Warteschlange), ablehnen, fallen oder Störung

Übrigens ein guter Text über WCF und MSMQ ist die chapther 9 von Progammig WCF Buch von Juval Löwy

Wenn Sie SQL-Server verwenden, dann sollten Sie eine verteilte Transaktion verwenden, da beide MSMQ und SQL-Server-Unterstützung es. Was passiert, ist, dass Sie Ihre Datenbank schreiben in einem Transaction Block wickeln und rufen scope.Complete () nur dann, wenn es gelingt. Wenn es fehlschlägt, dann, wenn die WCF-Methode gibt die Nachricht wieder in die Warteschlange gestellt werden, um wieder versucht zu werden. Hier ist eine gekürzte Fassung Code verwende ich:

    [OperationBehavior(TransactionScopeRequired=true, TransactionAutoComplete=true)]
    public void InsertRecord(RecordType record)
    {
        try
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                SqlConnection InsertConnection = new SqlConnection(ConnectionString);
                InsertConnection.Open();

                // Insert statements go here

                InsertConnection.Close();

                // Vote to commit the transaction if there were no failures
                scope.Complete();
            }
        }
        catch (Exception ex)
        {
            logger.WarnException(string.Format("Distributed transaction failure for {0}", 
                Transaction.Current.TransactionInformation.DistributedIdentifier.ToString()),
                ex);
        }
     }

Ich teste dies durch eine große, aber bekannte Anzahl von Aufzeichnungen Schlange stehen, lassen Sie WCF viele Threads beginnen viele von ihnen gleichzeitig (16 Fäden erreicht - 16 Meldungen aus sofort der Warteschlange) zu handhaben, töten dann den Prozess in der Mitte der Operationen. Wenn das Programm neu gestartet wird, wird die Nachrichten wieder aus der Warteschlange und verarbeitet wieder, als ob nichts passiert ist, und am Ende des Tests lesen Sie die Datenbank konsistent und hat keine fehlenden Aufzeichnungen.

Der Distributed Transaction Manager verfügt über eine Umgebungs Präsenz, und wenn Sie eine neue Instanz der Transaction schaffen es sucht automatisch für die aktuelle Transaktion im Rahmen des Verfahrens Invokation - die bereits von WCF erstellt werden sollte, wenn er die Nachricht aufgetaucht aus der Warteschlange und aufgerufen Ihre Methode.

Leider 2003 bin ich stecken unter Windows XP und Windows Server so ist, dass keine Option für mich. - (Ich werde das in meiner Frage erneut klären, wie ich diese Lösung nach der Einlieferung gefunden und realisierte ich es nicht benutzen konnte)

Ich fand, dass eine Lösung für Setup war ein benutzerdefinierter Handler, die meine Nachricht an einem anderen Warteschlange oder Gift Warteschlange verschieben würden und meinen Dienst neu starten. Das schien mir verrückt. Stellen Sie sich meine SQL Server war nach unten, wie oft der Dienst würde neu gestartet werden.

SO, was ich tun am Ende ist die Linie, so dass zu bemängeln und lassen Sie Nachrichten in der Warteschlange. Ich log auch eine fatale Botschaft an mein System-Logging-Dienst, dies geschehen ist. Sobald unser Problem behoben ist, starten Sie den öffentlichen Dienst und alle Nachrichten beginnen immer wieder verarbeitet werden.

Ich erkennen Wieder Verarbeitung diese Nachricht oder andere werden alle scheitern, warum also die Notwendigkeit, diese Nachricht und die andere in einer anderen Warteschlange zu bewegen. Ich kann meinen Dienst als auch stoppen und wieder starten, wenn alle wie erwartet funktioniert.

aogan, hat man die perfekte Antwort für MSMQ 4.0, aber leider nicht für mich

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top