(0) exportieren Drucken
Alle erweitern

Behandeln vorübergehender Kommunikationsfehler

Letzte Aktualisierung: September 2014

Um die Zuverlässigkeit einer Lösung zu verbessern, die die .NET-verwaltete API für Brokermessaging von Microsoft Azure Service Bus verwendet, empfiehlt es sich, einen einheitlichen Ansatz für die Behandlung vorübergehender bzw. zeitweiliger Fehler zu implementieren. Die Fehler können bei der Kommunikation zwischen der Lösung und der von Servicebus bereitgestellten cloudbasierten Messagingdienst-Infrastruktur für Warteschlangen- und Veröffentlichungs-/Abonnementvorgänge auftreten, die zudem eine hohe Mehrinstanzenfähigkeit aufweist.

Um die Zuverlässigkeit einer Lösung zu verbessern, die die .NET-verwaltete API für Brokermessaging von Servicebus verwendet, empfiehlt es sich, einen einheitlichen Ansatz für die Behandlung vorübergehender bzw. zeitweiliger Fehler zu implementieren. Die Fehler können bei der Kommunikation zwischen der Lösung und der von Servicebus bereitgestellten cloudbasierten Messagingdienst-Infrastruktur für Warteschlangen- und Veröffentlichungs-/Abonnementvorgänge auftreten, die zudem eine hohe Mehrinstanzenfähigkeit aufweist.

Bei der Implementierung eines bestimmten Verfahrens zur Erkennung vorübergehender Fehlerbedingungen können Sie auf bereits vorhandene technische Lösungen wie das Framework zur Behandlung vorübergehender Fehler zurückgreifen oder ein eigenes Verfahren entwickeln. In beiden Fällen müssen Sie sicherstellen, dass nur eine Teilmenge der Kommunikationsausnahmen als vorübergehend behandelt wird, bevor Sie versuchen, die Kommunikation nach den jeweiligen Fehlern wiederherzustellen.

In der hier aufgeführten Tabelle sind Ausnahmen aufgelistet, die durch die Implementierung von Wiederholungslogik kompensiert werden können:

 

Ausnahmetyp

Empfehlung

ServerBusyException

Diese Ausnahme kann durch einen zeitweiligen Fehler in der Messagingdienst-Infrastruktur von Servicebus verursacht werden, weil diese eine Anforderung aufgrund unnormaler Ladebedingungen zu diesem Zeitpunkt nicht verarbeiten kann. Der Client kann den Anforderungsversuch nach einer Verzögerungszeit wiederholen. In diesem Fall wäre eine Backoffverzögerung von Vorteil, um den Server nicht unnötig zu belasten.

MessagingCommunicationException

Diese Ausnahme deutet auf einen Kommunikationsfehler hin, der auftreten kann, wenn zwischen dem Messagingclient und der Servicebus-Infrastruktur keine Verbindung hergestellt werden kann. In den meisten Fällen kann dieser Fehler als vorübergehend angesehen werden, sofern eine Netzwerkverbindung besteht. Der Client kann versuchen, den Vorgang, der zu dieser Ausnahme geführt hat, zu wiederholen. Außerdem sollte überprüft werden, ob der Dienst zur Auflösung von Domänennamen (DNS) funktionsfähig ist, da dieser Fehler u. U. darauf hinweist, dass der Name des Zielhosts nicht aufgelöst werden kann.

TimeoutException

Die Ausnahme gibt an, dass die Messagingdienst-Infrastruktur von Servicebus nicht innerhalb der angegebenen, durch die OperationTimeout-Einstellung vorgegebenen Zeitspanne auf den angeforderten Vorgang reagiert hat. Es ist trotzdem möglich, dass der angeforderte Vorgang abgeschlossen wurde, allerdings wurde die Antwort aufgrund von Netzwerk- oder anderen Infrastrukturverzögerungen u. U. nicht rechtzeitig an den Client übermittelt. Dieser Ausnahmetyp sollte mit Vorsicht behandelt werden. Wenn eine Nachricht an eine Warteschlange übermittelt wurde, für die Antwort aber ein Timeout aufgetreten ist, wird durch das erneute Senden der ursprünglichen Nachricht ein Duplikat erzeugt.

Ausführlichere Informationen zu den verschiedenen Ausnahmetypen, die durch die Messaging-API von Servicebus gemeldet werden können, finden Sie im Thema Messagingausnahmen.

noteHinweis
Beachten Sie bei der Behandlung vorübergehender Kommunikationsfehler vorübergehende Ausnahmen, die in Form äußerer Ausnahmen eines anderen Typs auftreten können. Beispielsweise kann ein Timeout in Form eines Kommunikationsfehlers, der das ursprüngliche Timeout als innere Ausnahme verbirgt, an den Aufrufer zurückgegeben werden. Aus diesem Grund wird empfohlen, alle inneren Ausnahmen des jeweiligen Ausnahmeobjekts auf rekursive Weise zu überprüfen, damit vorübergehende Kommunikationsfehler zuverlässig erkannt werden können. Die ServiceBusTransientErrorDetectionStrategy-Klasse im Framework zur Behandlung vorübergehender Fehler bietet ein Beispiel zur Vorgehensweise.

Im folgenden Codeausschnitt wird veranschaulicht, wie Sie asynchron eine Nachricht an ein Servicebus-Thema senden und gleichzeitig sicherstellen, dass alle bekannten vorübergehenden Fehler durch einen Wiederholungsvorgang kompensiert werden. Beachten Sie, dass dieses Codebeispiel eine Abhängigkeit vom Framework zur Behandlung vorübergehender Fehler aufweist.

var credentials = TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerSecret);
var address = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, String.Empty);
var messagingFactory = MessagingFactory.Create(address, credentials);
var topicClient = messagingFactory.CreateTopicClient(topicPath);
var retryPolicy = new RetryPolicy<ServiceBusTransientErrorDetectionStrategy>(RetryPolicy.DefaultClientRetryCount);
// Create an instance of the object that represents message payload.
var payload = XDocument.Load("InventoryFile.xml");
// Declare a BrokeredMessage instance outside so that it can be reused across all 3 delegates below.
BrokeredMessage msg = null;
// Use a retry policy to execute the Send action in an asynchronous and reliable fashion.
retryPolicy.ExecuteAction
(
    (cb) =>
    {
        // A new BrokeredMessage instance must be created each time we send it. Reusing the original BrokeredMessage instance may not 
        // work as the state of its BodyStream cannot be guaranteed to be readable from the beginning.
        msg = new BrokeredMessage(payload.Root, new DataContractSerializer(typeof(XElement)));
        // Send the event asynchronously.
        topicClient.BeginSend(msg, cb, null);
    },
    (ar) =>
    {
        try
        {
            // Complete the asynchronous operation. 
            // This may throw an exception that will be handled internally by the retry policy.
            topicClient.EndSend(ar);
        }
        finally
        {
            // Ensure that any resources allocated by a BrokeredMessage instance are released.
            if (msg != null)
            {
                msg.Dispose();
                msg = null;
            }
        }
    },
    (ex) =>
    {
        // Always dispose the BrokeredMessage instance even if the send 
        // operation has completed unsuccessfully.
        if (msg != null)
        {
            msg.Dispose();
            msg = null;
        }
        // Always log exceptions.
        Trace.TraceError(ex.Message);
    }
);

Das nächste Codebeispiel veranschaulicht, wie auf zuverlässige Weise ein neues Servicebus-Thema erstellt bzw. ein vorhandenes abgerufen wird. Dieser Code weist auch eine Abhängigkeit vom Framework zur Behandlung vorübergehender Fehler auf, das automatisch versucht, den entsprechenden Verwaltungsvorgang zu wiederholen, wenn dieser aufgrund zeitweiliger Verbindungsprobleme oder anderer vorübergehender Fehlerbedingungen nicht erfolgreich ausgeführt werden kann:

public TopicDescription GetOrCreateTopic(string issuerName, string issuerSecret, string serviceNamespace, string topicName)
{
    // Must validate all input parameters here. Use Code Contracts or build your own validation.
    var credentials = TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerSecret);
    var address = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, String.Empty);
    var nsManager = new NamespaceManager(address, credentials);
    var retryPolicy = new RetryPolicy<ServiceBusTransientErrorDetectionStrategy>(RetryPolicy.DefaultClientRetryCount);
    TopicDescription topic = null;
    bool createNew = false;
    try
    {
        // First, let's see if a topic with the specified name already exists.
        topic = retryPolicy.ExecuteAction<TopicDescription>(() => { return nsManager.GetTopic(topicName); });
        createNew = (topic == null);
    }
    catch (MessagingEntityNotFoundException)
    {
        // Looks like the topic does not exist. We should create a new one.
        createNew = true;
    }
    // If a topic with the specified name doesn't exist, it will be auto-created.
    if (createNew)
    {
        try
        {
            var newTopic = new TopicDescription(topicName);
            topic = retryPolicy.ExecuteAction<TopicDescription>(() => { return nsManager.CreateTopic(newTopic); });
        }
        catch (MessagingEntityAlreadyExistsException)
        {
            // A topic under the same name was already created by someone else, 
            // perhaps by another instance. Let's just use it.
            topic = retryPolicy.ExecuteAction<TopicDescription>(() => { return nsManager.GetTopic(topicName); });
        }
    }
    return topic;
}

Grundsätzlich wird empfohlen, die Fehlerwahrscheinlichkeit abzuwägen und zu bestimmen, ob zusätzliche Resilienz implementiert werden kann. Vorübergehende Fehlerbedingungen betreffen praktisch alle Arten von Messagingvorgängen. Daher wird bei Aufrufen der API für Brokermessaging empfohlen, geeignete Maßnahmen vorzusehen, die immer eine Wiederherstellung nach zeitweiligen Problemen ermöglichen.

Microsoft führt eine Onlineumfrage durch, um Ihre Meinung zur MSDN-Website zu erfahren. Wenn Sie sich zur Teilnahme entscheiden, wird Ihnen die Onlineumfrage angezeigt, sobald Sie die MSDN-Website verlassen.

Möchten Sie an der Umfrage teilnehmen?
Anzeigen:
© 2014 Microsoft