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

Le modèle d’exécution fiable de Durable Functions nécessite que les orchestrations soient déterministes, ce qui crée un défi lorsque vous déployez des mises à jour. Lorsqu’un déploiement contient des modifications incompatibles, telles que des signatures de fonction d’activité modifiées ou une logique d’orchestrateur modifiée, les instances d’orchestration actives échouent. Cette situation pose particulièrement un problème pour les orchestrations longues, qui peuvent représenter des heures ou des jours de travail.

Note

Les stratégies de cet article supposent que vous utilisez le fournisseur de stockage Azure par défaut pour Durable Functions. Si vous utilisez un autre fournisseur de stockage, les conseils peuvent ne pas s’appliquer. La stratégie de contrôle de version d’orchestration est l’exception : elle fonctionne avec n’importe quel serveur principal de stockage. Pour plus d’informations sur les options du fournisseur de stockage, consultez Durable Functions fournisseurs de stockage.

Le tableau suivant compare quatre stratégies pour atteindre un déploiement sans temps d’arrêt. Choisissez la stratégie qui correspond le mieux à votre charge de travail :

Stratégie Quand utiliser Avantages Inconvénients
Versionnage d’orchestration (recommandé) Applications avec des changements incompatibles nécessitant plusieurs versions d’orchestration fonctionnant en parallèle. Active les déploiements sans temps d’arrêt avec des changements cassants.
Fonctionnalité intégrée nécessitant une configuration minimale.
Fonctionne avec n’importe quel serveur principal de stockage.
Nécessite des modifications minutieuses du code d’orchestrateur pour la compatibilité des versions.
Versionnage basé sur le nom Les applications avec des modifications de rupture peu fréquentes où la simplicité est privilégiée. 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èmes avec orchestrations de courte durée (moins de 24 heures) et écarts prévisibles entre les exécutions. 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èmes avec des orchestrations fonctionnant en continu (plus de 24 heures) ou des exécutions fréquemment chevauchantes sans périodes d'inactivité. 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.
Il est possible d'atteindre le nombre maximal d'applications de fonction autorisées par votre abonnement (la valeur par défaut est 100).

Gestion des versions d’orchestration

La fonctionnalité de versionnage d’orchestration est la stratégie recommandée pour les déploiements sans temps d’arrêt avec des modifications rompant la compatibilité. Il permet à différentes versions d’orchestrations de coexister et d’exécuter simultanément sans conflit.

Avec le contrôle de version d’orchestration :

  • Chaque instance d’orchestration obtient une version associée définitivement à celle-ci lors de sa création.
  • Les workers exécutant des versions plus récentes d’orchestrateur peuvent continuer à exécuter des instances de version plus anciennes.
  • Les workers exécutant des versions d’orchestration plus anciennes ne peuvent pas exécuter des instances de version plus récentes.
  • Les fonctions Orchestrator peuvent examiner leur version et leur exécution de branche en conséquence.

Cette approche facilite les mises à niveau propagées où les workers exécutant différentes versions de votre application peuvent coexister en toute sécurité. Contrairement aux autres stratégies de cet article, le contrôle de version d’orchestration est indépendant du back-end et fonctionne avec n’importe quel fournisseur de stockage.

Pour connaître les étapes d’implémentation complètes, notamment la configuration du contrôle de version, la gestion des branchements de version dans le code d’orchestrateur et la gestion des mises à niveau propagées, consultez Gestion des versions d’orchestration.

Les stratégies restantes sont des alternatives pour les scénarios dans lesquels le versionnage de l'orchestration n’est pas approprié.

Versionnage basé sur le nom

Avec cette stratégie, vous créez de nouvelles versions de vos fonctions en même temps que les anciennes versions de la même application de fonction. La version de chaque fonction fait partie de son nom (par exemple, MyOrchestrator_v1, MyOrchestrator_v2). Étant donné que les versions précédentes sont conservées, les instances d’orchestration en cours peuvent continuer à les référencer. 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. Le diagramme suivant illustre cette approche.

Screenshot du diagramme de stratégie de gestion de version basée sur le nom montrant comment les versions de fonction coexistent dans un Durable Functions app.

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.

Note

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 et l’utilisation de nouveaux emplacements de déploiement, consultez Azure Functions emplacements de déploiement.

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 de connexion d’un compte de stockage partagé. Cette 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 functions. Pour bénéficier du niveau de sécurité le plus élevé, nous vous recommandons d’utiliser une connexion d’identité managée à votre compte de stockage.

  3. Pour chaque emplacement, créez un paramètre d’application, par exemple, DurableManagementStorage. Définissez sa valeur sur la chaîne de connexion de différents comptes de stockage. Ces comptes de stockage sont utilisés par l’extension Durable Functions pour 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. Là encore, les connexions basées sur des identités managées sont les plus sécurisées.

  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.

Capture d'écran des slots de déploiement et de la configuration des comptes de stockage avant l’échange de slots pour le déploiement sans interruption des fonctions durables.

exemple de host.json

Le fragment JSON suivant montre le paramètre chaîne de connexion dans le fichier host.json.

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

Note

Pour les applications Functions 1.x héritées, utilisez la azureStorageConnectionStringName propriété directement dans la durableTask section au lieu de storageProvider.connectionStringName.

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. Lorsque vous utilisez Azure Pipelines, vous pouvez créer une fonction qui vérifie ces conditions, comme dans l'exemple C# suivant. Le même modèle s’applique à d’autres langages : interrogez les instances d’orchestration avec Pending ou Running d’état et retournez si elles existent.

[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

Capture d'écran d'une passerelle de déploiement Azure Pipelines pour le déploiement sans interruption des Durable Functions.

Azure Pipelines vérifie votre application de fonctions pour les instances d’orchestration en cours d’exécution avant le démarrage de votre déploiement.

Screenshot d’une vérification de la porte de déploiement Azure Pipelines en cours d’exécution pour les instances d’orchestration.

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

Capture d'écran de la nouvelle version de l’application Durable Functions déployée sur l’emplacement intermédiaire pendant le déploiement sans interruption.

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.

Capture d'écran de l’achèvement de l’échange d’emplacement avec les paramètres de l’application Durable Functions déplacés vers la production.

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 plus d’informations, consultez Task hubs dans Durable Functions.

Routage d’applications

Cette stratégie est la plus complexe, mais elle est la seule option pour les systèmes avec des orchestrations en cours d’exécution continue qui n’ont jamais de fenêtre inactive pour les échanges d’emplacements.

Pour cette stratégie, vous créez un routeur application devant votre Durable Functions, par exemple une fonction Azure avec des déclencheurs HTTP ou une instance gestion des API qui route en fonction des en-têtes de version. Le routeur est responsable des opérations suivantes :

  • Déploiement de l’application de fonction.
  • Gestion de la version de l’application qui est active.
  • Routage des demandes d’orchestration vers l’application de fonction appropriée en fonction de la version.

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

  1. Crée une nouvelle application de fonctions dans Azure.
  2. Déploie le code de votre application de fonction dans 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 de votre application qui est déployée sur quelle application de fonction dans Azure.

Capture d'écran du routage et du flux de déploiement des applications pour des fonctions durables avec un déploiement sans interruption.

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.

Capture d'écran du routage des applications lorsqu'il n'y a aucun changement disruptif dans un déploiement de Durable Functions.

Quand vous déployez une nouvelle version de votre application avec un changement cassant, vous pouvez incrémenter la version majeure ou mineure. Ensuite, le routeur d’application crée une application de fonction dans Azure, la déploie et lui achemine les demandes de 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.

Capture d'écran du routage d'application pour un déploiement Durable Functions avec des modifications non rétrocompatibles.

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 les instances dans Durable Functions dans Azure.

Capture d'écran des paramètres du magasin de suivi partagé entre les applications Durable Functions versionnées.

Étapes suivantes