2017-07-11 2 views
0

J'ai une fonction Azure (basée sur les nouvelles fonctions C# au lieu des anciennes fonctions .csx) qui est déclenchée lorsqu'un message arrive dans une file d'attente Azure Service Bus. Une fois la fonction déclenchée, elle commence à traiter le message du bus de service. Il décode le message, lit un tas de bases de données, met à jour un tas d'autres, etc ... Cela peut prendre jusqu'à 30 minutes à la fois. Comme, ce n'est pas un processus sensible au temps, 30 minutes ou même 60 minutes ne sont pas un problème. Le problème est que pendant ce temps, Azure Function semble se remettre en marche et reprend le même message encore et encore et le retraite. Ceci est un problème et cause des problèmes dans notre logique métier. Donc, la question est: pouvons-nous forcer la fonction Azure à fonctionner en mode singleton? Ou si ce n'est pas possible, comment changeons-nous l'intervalle d'interrogation?Fonction Azure exécutée plusieurs fois pour le même message de file d'attente de bus de service

+0

Votre application de fonction a-t-elle été créée dans le cadre du plan de service d'application ou du plan de consommation? Sous Plan de service de l'application, assurez-vous que AlwaysOn est activé. Sous le plan de consommation, la fonction App est terminée après 5 minutes (configurable pour étendre à 10 minutes, voir la valeur "functionTimeout" à https://github.com/Azure/azure-webjobs-sdk-script/wiki/host.json), ce qui peut expliquer le comportement que vous voyez. –

+0

J'ai le plan de service App. Ma fonction ne se termine pas. En fait, le contraire est en train de se produire. Plusieurs fonctions traitent le message. – Yasir

Répondre

2

Le problème est lié au réglage Service Bus ...

Ce qui se passe est que le message est ajouté à la file d'attente, le message est alors donné à la fonction et un verrou est placé sur ce message afin que Aucun autre consommateur ne peut voir/traiter ce message pendant que vous avez un verrou dessus. Si au cours de cette période de verrouillage, vous ne dites pas au bus de service que vous avez traité le fichier, ou pour étendre le verrou, le verrou est supprimé du message et il devient visible aux autres services qui traiteront ensuite ce message , c'est ce que tu vois. Heureusement, les fonctions Azure peuvent automatiquement renouveler le verrouillage pour vous. Dans le fichier host.json, un paramètre autoRenewTimeout spécifie le délai pendant lequel vous souhaitez que les fonctions Azure continuent de renouveler le verrouillage.

https://github.com/Azure/azure-webjobs-sdk-script/wiki/host.json

"serviceBus": { 
    // the maximum duration within which the message lock will be renewed automatically. 
    "autoRenewTimeout": "00:05:00" 
}, 
3

AutoRenewTimeout est pas aussi grande que suggéré. Il y a un inconvénient dont vous devez être conscient. C'est not a guaranteed operation. Étant une opération initiée côté client, il peut et parfois échouera, vous laissant dans le même état que vous êtes aujourd'hui.

Ce que vous pouvez faire pour résoudre ce problème est de revoir votre conception. Si vous avez un long processus en cours, alors vous traitez le message, et passez le traitement à quelque chose qui peut fonctionner plus longtemps que MaxLockDuration. Le fait que votre fonction prenne autant de temps indique que vous avez un long processus d'exécution. La messagerie n'est pas conçue pour cela.

L'une des solutions possibles serait d'obtenir un message, d'enregistrer l'intention de traitement dans une table de stockage. Avoir une autre table de stockage déclenchée fonction pour lancer le traitement qui pourrait prendre X minutes. Marquez-le comme un singleton. Ce faisant, vous traiterez vos messages en parallèle, en écrivant "demande de traitement de longue durée" dans la table de stockage, en complétant la messagerie du bus de service et par conséquent en ne déclenchant pas leur re-traitement. Avec le traitement de longue durée, vous pouvez décider comment gérer les cas de défaillance.

Espérons que ça aide.

+0

Quand vous dites "Marquez-le comme un singleton", à quoi faites-vous référence? Et comment puis-je le marquer comme un singleton? – Yasir

+0

L'autre fonction déclenchée par la table de stockage. J'ai implémenté un processus similaire avec NServiceBus et Service Bus. Vous trouverez le code et le schéma ici: https://docs.particular.net/samples/azure/azure-service-bus-long-running/ Avec l'approche des fonctions, votre fonction de longue durée (processeur) n'a pas pour interroger, ce serait déclenché. –

+1

Je suggère d'utiliser le https://github.com/Azure/azure-functions-durable-extension, qui fournit les capacités de longue durée/orchestration dont vous avez besoin –