Déploiement sans temps d’arrêt pour Durable Functions

Pour permettre un bon fonctionnement du modèle d’exécution fiable de Durable Functions, les orchestrations doivent être déterministes, ce qui représente un point supplémentaire à prendre en compte quand vous déployez des mises à jour. Quand un déploiement contient des changements apportés aux signatures de fonction d’activité ou à la logique d’orchestrateur, les instances d’orchestration actives cessent de fonctionner correctement. Cette situation est particulièrement problématique pour les instances d’orchestration de longue durée, qui peuvent représenter des heures ou des jours de travail.

Pour éviter ces échecs, vous avez deux options :

  • Retardez votre déploiement jusqu’à ce que toutes les instances d’orchestration en cours d’exécution soient terminées.
  • Assurez-vous que toutes les instances d’orchestration en cours d’exécution utilisent les versions existantes de vos fonctions.

Le tableau suivant compare les trois stratégies principales qui permettent d’effectuer un déploiement sans temps d’arrêt pour Durable Functions :

Stratégie Quand l’utiliser Avantages Inconvénients
Contrôle de version Applications qui ne font pas l’objet de changements cassants. Simple à implémenter. Augmentation de la taille de l’application de fonction en mémoire et du nombre de fonctions.
Duplication de code.
Vérification de l’état sur un emplacement Système qui n’a pas d’orchestrations de longue durée de plus de 24 heures ou qui se chevauchent fréquemment. Code base simple.
Ne nécessite pas de gestion d’application de fonction supplémentaire.
Nécessite un compte de stockage supplémentaire ou une gestion du hub de tâches.
Nécessite des périodes pendant lesquelles aucune orchestration n’est en cours d’exécution.
Routage d’applications Système qui n’a pas de périodes pendant lesquelles les orchestrations ne sont pas exécutées, par exemple les périodes ayant des orchestrations de plus de 24 heures ou dont les orchestrations se chevauchent fréquemment. Prend en charge les nouvelles versions des systèmes dont les orchestrations s’exécutent en permanence et comportent des changements cassants. Nécessite un routeur d’applications intelligent.
Peut atteindre la limite du nombre d’applications de fonction autorisées par votre abonnement. La valeur par défaut est 100.

Le reste de ce document décrit ces stratégies plus en détail.

Notes

Les descriptions de ces stratégies de déploiement sans interruption de service supposent que vous utilisez le fournisseur Stockage Azure par défaut pour Durable Functions. Les instructions peuvent ne pas être appropriées si vous utilisez un fournisseur de stockage autre que le fournisseur Stockage Azure par défaut. Pour plus d’informations sur les différentes options du fournisseur de stockage et leur comparaison, consultez la documentation sur les fournisseurs de stockage Durable Functions.

Contrôle de version

Définissez de nouvelles versions de vos fonctions, et laissez les anciennes versions dans votre application de fonction. Comme vous pouvez le voir dans le diagramme, la version d’une fonction devient partie intégrante de son nom. Dans la mesure où les versions précédentes des fonctions sont conservées, les instances d’orchestration actives peuvent continuer à les référencer. Pendant ce temps, les demandes de nouvelles instances d’orchestration appellent la dernière version, que votre fonction cliente d’orchestration peut référencer à partir d’un paramètre d’application.

Versioning strategy

Dans cette stratégie, chaque fonction doit être copiée, et ses références à d’autres fonctions doivent être mises à jour. Vous pouvez faciliter la tâche en écrivant un script. Voici un exemple de projet avec un script de migration.

Notes

Cette stratégie utilise des emplacements de déploiement pour éviter les temps d’arrêt durant le déploiement. Pour plus d’informations sur la création d’emplacements de déploiement et sur leur utilisation, consultez Emplacements de déploiement Azure Functions.

Vérification de l’état sur un emplacement

Pendant que la version actuelle de votre application de fonction s’exécute dans votre emplacement de production, déployez la nouvelle version de votre application de fonction sur votre emplacement de préproduction. Avant de permuter vos emplacements de production et de préproduction, vérifiez si des instances d’orchestration sont en cours d’exécution. Une fois que toutes les instances d’orchestration ont fini de s’exécuter, vous pouvez effectuer l’échange. Cette stratégie fonctionne quand vous avez des périodes prévisibles pendant lesquelles aucune instance d’orchestration n’est active. Il s’agit de la meilleure approche quand vos orchestrations ne sont pas longues et que leurs exécutions ne se chevauchent pas fréquemment.

Configuration de l’application de fonction

Utilisez la procédure suivante pour mettre en œuvre ce scénario.

  1. Ajoutez des emplacements de déploiement à votre application de fonction pour la préproduction et la production.

  2. Pour chaque emplacement, affectez au paramètre d’application AzureWebJobsStorage la chaîne de connexion d’un compte de stockage partagé. Cette chaîne de connexion de compte de stockage est utilisée par le runtime Azure Functions pour stocker en toute sécurité les clés d’accès des fonctions.

  3. Pour chaque emplacement, créez un paramètre d’application, par exemple, DurableManagementStorage. Définissez sa valeur en fonction de la chaîne de connexion de différents comptes de stockage. Ces comptes de stockage sont utilisés par l’extension Durable Functions pour l’exécution fiable. Utilisez un compte de stockage distinct pour chaque emplacement. Ne marquez pas ce paramètre en tant que paramètre d’emplacement de déploiement.

  4. Dans la section durableTask du fichier host.json de votre application de fonction, spécifiez connectionStringName (Durable 2.x) ou azureStorageConnectionStringName (Durable 1.x) en tant que nom du paramètre d’application créé à l’étape 3.

Le diagramme suivant illustre la configuration décrite pour les emplacements de déploiement et les comptes de stockage. Dans ce scénario de prédéploiement potentiel, la version 2 d’une application de fonction s’exécute dans l’emplacement de production, alors que la version 1 reste dans l’emplacement de préproduction.

Deployment slots and storage accounts

Exemples host.json

Les fragments JSON suivants sont des exemples de paramètres de chaîne de connexion dans le fichier host.json.

Functions 2.0

{
  "version": 2.0,
  "extensions": {
    "durableTask": {
      "hubName": "MyTaskHub",
      "storageProvider": {
        "connectionStringName": "DurableManagementStorage"
      }
    }
  }
}

Functions 1.x

{
  "durableTask": {
    "azureStorageConnectionStringName": "DurableManagementStorage"
  }
}

Configuration du pipeline CI/CD

Configurez votre pipeline CI/CD pour le déploiement uniquement quand votre application de fonction n’a aucune instance d’orchestration en attente ou en cours d’exécution. Quand vous utilisez Azure Pipelines, vous pouvez créer une fonction qui vérifie ces conditions, comme dans l’exemple suivant :

[FunctionName("StatusCheck")]
public static async Task<IActionResult> StatusCheck(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    var runtimeStatus = new List<OrchestrationRuntimeStatus>();

    runtimeStatus.Add(OrchestrationRuntimeStatus.Pending);
    runtimeStatus.Add(OrchestrationRuntimeStatus.Running);

    var result = await client.ListInstancesAsync(new OrchestrationStatusQueryCondition() { RuntimeStatus = runtimeStatus }, CancellationToken.None);
    return (ActionResult)new OkObjectResult(new { HasRunning = result.DurableOrchestrationState.Any() });
}

Configurez ensuite la porte de préproduction pour qu’elle attende la fin de l’exécution de toutes les orchestrations en cours. Pour plus d’informations, consultez Contrôle du déploiement de mises en production à l’aide de portes

Deployment gate

Azure Pipelines vérifie si votre application de fonction exécute des instances d’orchestration avant le démarrage du déploiement.

Deployment gate (running)

À présent, la nouvelle version de votre application de fonction doit être déployée sur l’emplacement de préproduction.

Staging slot

Enfin, permutez les emplacements.

Les paramètres d’application qui ne sont pas marqués en tant que paramètres d’emplacement de déploiement sont également permutés. Ainsi, l’application version 2 conserve sa référence au compte de stockage A. Dans la mesure où l’état d’orchestration est suivi dans le compte de stockage, les orchestrations exécutées sur l’application version 2 continuent de s’exécuter dans le nouvel emplacement, sans interruption.

Deployment slot

Si vous souhaitez utiliser le même compte de stockage pour les deux emplacements, changez les noms de vos hubs de tâches. Dans ce cas, vous devez gérer l’état de vos emplacements et les paramètres HubName de votre application. Pour en savoir plus, consultez Hubs de tâches dans Durable Functions.

Routage d’applications

Cette stratégie est la plus complexe. Toutefois, elle peut être utilisée pour les applications de fonction qui n’ont pas d’intervalles entre les exécutions d’orchestrations.

Pour cette stratégie, vous devez créer un routeur d’applications devant votre extension Durable Functions. Ce routeur peut être implémenté avec Durable Functions. Le routeur a la responsabilité d’effectuer les opérations suivantes :

  • Déployez l’application de fonction.
  • Gérer la version de Durable Functions.
  • Router les demandes d’orchestration vers les applications de fonction.

La première fois qu’une demande d’orchestration est reçue, le routeur effectue les tâches suivantes :

  1. Il crée une application de fonction dans Azure.
  2. Il déploie le code de votre application de fonction sur la nouvelle application de fonction dans Azure.
  3. Il transmet la demande d’orchestration à la nouvelle application.

Le routeur gère l’état de la version du code d’application déployée sur l’application de fonction dans Azure.

Application routing (first time)

Le routeur dirige les demandes de déploiement et d’orchestration vers l’application de fonction appropriée selon la version envoyée avec la demande. Il ignore la version du correctif.

Quand vous déployez une nouvelle version de votre application sans changement cassant, vous pouvez incrémenter la version du correctif. Le routeur se déploie sur votre application de fonction existante et envoie les demandes relatives à l’ancienne et à la nouvelle version du code, qui sont routées vers la même application de fonction.

Application routing (no breaking change)

Quand vous déployez une nouvelle version de votre application avec un changement cassant, vous pouvez incrémenter la version majeure ou mineure. Le routeur d’applications crée ensuite une application de fonction dans Azure, s’y déploie et route vers celle-ci les demandes relatives à la nouvelle version de votre application. Dans le diagramme suivant, l’exécution d’orchestrations sur la version 1.0.1 de l’application continue de s’effectuer. Toutefois, les demandes relatives à la version 1.1.0 sont routées vers la nouvelle application de fonction.

Application routing (breaking change)

Le routeur supervise l’état des orchestrations sur la version 1.0.1, puis supprime les applications à la fin de l’exécution de toutes les orchestrations.

Suivi des paramètres de stockage

Chaque application de fonction doit utiliser des files d’attente de planification distinctes, éventuellement dans des comptes de stockage distincts. Si vous souhaitez interroger toutes les instances d’orchestration parmi toutes les versions de votre application, vous pouvez partager les tables d’instance et d’historique entre vos applications de fonction. Vous pouvez partager les tables en configurant les paramètres trackingStoreConnectionStringName et trackingStoreNamePrefix dans le fichier de paramètres host.json pour utiliser partout les mêmes valeurs.

Pour plus d’informations, consultez Gérer des instances dans Durable Functions dans Azure.

Tracking store settings

Étapes suivantes