37 votes

Forcer EventProcessorHost de re-livrer a échoué Azure Événement Hub eventData à IEventProcessor.ProcessEvents méthode

L'application utilise .NET 4.6.1 et le Microsoft.Azure.ServiceBus.EventProcessorHost nuget package v2.0.2, ainsi que la dépendance WindowsAzure.ServiceBus paquet v3.0.1 pour le processus d'Azur Event Hub messages.

L'application dispose d'une mise en œuvre de l' IEventProcessor. Lorsqu'une exception non gérée s'est jetée de la ProcessEventsAsync méthode de l' EventProcessorHost jamais re-envoie ces messages à l'instance en cours d' IEventProcessor. (Pour l'anecdote, il sera ré-envoyer si l'application d'hébergement est arrêté et redémarré ou si le bail est perdu et ré-obtenu.)

Est-il un moyen pour forcer le message d'événement qui a entraîné une exception à être ré-envoyé par EventProcessorHost de la IEventProcessor mise en œuvre?

Une solution possible est présentée dans le présent commentaire sur une presque identique à la question: Remettre non transformés EventHub messages dans IEventProcessor.ProcessEventsAsync

Le commentaire suggère la tenue d'une copie du dernier traité avec succès des messages d'événement et la vérification explicitement à l'aide de ce message lorsqu'une exception se produit en ProcessEventsAsync. Cependant, après la mise en œuvre et de tester une telle solution, l' EventProcessorHost n'est toujours pas ré-envoyer. La mise en œuvre est assez simple:

private EventData _lastSuccessfulEvent;

public async Task ProcessEventsAsync(
    PartitionContext context,
    IEnumerable<EventData> messages)
{
    try
    {
        await ProcessEvents(context, messages);     // does actual processing, may throw exception
        _lastSuccessfulEvent = messages
            .OrderByDescending(ed => ed.SequenceNumber)
            .First();
    }
    catch(Exception ex)
    {
        await context.CheckpointAsync(_lastSuccessfulEvent);
    }
}

Une analyse de choses en action: enter image description here

Partielle d'un journal de l'échantillon est disponible ici: https://gist.github.com/ttbjj/4781aa992941e00e4e15e0bf1c45f316#file-gistfile1-txt

18voto

Sreeram Garlapati Points 2853

TLDR: Le seul moyen fiable pour re-jouer de l'échec d'un lot d'événements à l' IEventProcessor.ProcessEventsAsync est - Shutdown le EventProcessorHost(aka EPH) immédiatement - soit en utilisant eph.UnregisterEventProcessorAsync() ou par la terminaison du processus - en fonction de la situation. Cela permettra à d'autres EPH instances d'acquérir le bail pour cette partition & start, à partir du point de contrôle précédent.

Avant d'expliquer ce - que je veux à l'appel, c'est une excellente Question, & en effet, a été l'un des plus difficiles des choix de conception que nous avons dû faire pour EPH. De mon point de vue, c'était un trade-off b/w: usability/supportability de la EPH - cadre, plus de Technical-Correctness.

Situation idéale aurait été: Lorsque l'utilisateur-code en IEventProcessorImpl.ProcessEventsAsync déclenche une Exception - EPH bibliothèque ne devriez pas prendre ce. Il aurait dû laisser cette Exception - crash le processus & la crash-dump montre clairement l' callstack responsable. Je crois encore - c'est le plus technically-correctde la solution.

Situation actuelle: Le contrat d' IEventProcessorImpl.ProcessEventsAsync API & EPH est,

  1. tant que EventData peut être reçue à partir de EventHubs service - continuer en invoquant l'utilisateur de rappel (IEventProcessorImplementation.ProcessEventsAsync) avec l' EventData's & si l'utilisateur de rappel jette les erreurs, tout en invoquant, informer EventProcessorOptions.ExceptionReceived.
  2. L'utilisateur code à l'intérieur d' IEventProcessorImpl.ProcessEventsAsync doit gérer toutes les erreurs et de les incorporer Retry's que nécessaire. EPH ne fixent pas de délai d'attente sur cette call-back pour donner aux utilisateurs un contrôle complet sur le traitement en temps.
  3. Si un événement spécifique est la cause de la difficulté de la marque de l' EventData avec une propriété particulière - par ex:type=poison-event et envoyez-la à nouveau pour le même EventHub(inclure un lien vers l'événement réel, de les copier à l' EventData.Offset et SequenceNumber dans le Nouveau EventData.ApplicationProperties) ou fwd pour un SERVICEBUS File d'attente ou à les stocker ailleurs, fondamentalement, identifier et reporter le traitement de la poison-événement.
  4. si vous avez traité tous les cas possibles et sont toujours en cours d'exécution en Exceptions - catch em & shutdown EPH ou failfast le processus avec cette exception. Lorsque l' EPH revient - il va commencer à partir d'où-il-gauche.

Pourquoi ne case de pointage "à l'ancienne événement" PAS de travail (lire ceci pour comprendre EPH en général):

En coulisses, EPH est en cours d'exécution d'une pompe par EventHub Consumergroup partition du récepteur - dont le travail est de démarrer le récepteur à partir d'un checkpoint (si présent) et de créer une instance dédiée de IEventProcessor de la mise en œuvre et ensuite, receive provenant de l'organisme de EventHub partition spécifiée Offset dans le point de contrôle (si non présent - EventProcessorOptions.initialOffsetProvider) et, éventuellement, invoquer IEventProcessorImpl.ProcessEventsAsync. Le but de l' Checkpoint est d'être en mesure fiable de commencer le traitement des messages, lorsque l' EPH processus Shutsdown et de la propriété de la Partition est déplacé vers un autre EPH des cas. Donc, checkpoint sera consommée uniquement lors du démarrage de la POMPE et de ne PAS être lu, une fois que la pompe a commencé.

Comme je l'ai écris, EPH est à la version 2.2.10...

-2voto

Itay Podhajcer Points 1092

Réponse Simple: Avez-vous essayé EventProcessorHost.ResetConnection(string partiotionId)?

Réponse Complexe: Il pourrait être une architecture problème qui doit adressée à votre fin, pourquoi le traitement de l'échec? était-ce une erreur passagère? est la nouvelle tentative de la logique de traitement est un scénario possible? Et ainsi de suite...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X