Que sont les déploiements Canary et pourquoi sauveront-ils votre production ?
\nAvez-vous déjà déployé une mise à jour à minuit en priant pour que rien ne plante ? Ça vous parle. Et si je vous disais qu'il est possible de tester du nouveau code sur des utilisateurs réels, mais sans que personne n'en souffre ? Il s'agit des déploiements canary — une stratégie de déploiement où la nouvelle version de l'application reçoit d'abord seulement une petite partie du trafic. Si tout va bien, le trafic augmente. Sinon, un rollback en quelques secondes.
\nDans le monde .NET et C#, c'est particulièrement pertinent : microservices, charges élevées, exigences de stabilité. Nous allons écrire du code, configurer un déploiement canary et analyser des exemples concrets. C'est parti !
\n\nPourquoi Canary n'est pas qu'un mot à la mode ?
\nLe traditionnel déploiement blue-green bascule tout le trafic d'un coup. La mise à jour progressive (rolling update) se fait progressivement, mais sans contrôle fin. Le Canary vous donne un super-pouvoir : vous déployez une nouvelle version, mais vous dirigez, disons, 5 % des utilisateurs vers elle. Les 95 % restants travaillent sur l'ancienne version stable. Vous surveillez les métriques, les erreurs, les latences. Si tout va bien, vous augmentez progressivement le pourcentage jusqu'à 100. Sinon, vous désactivez simplement le canary.
\nPour un développeur C#, c'est particulièrement pratique : nous pouvons utiliser les outils intégrés d'ASP.NET Core, Kubernetes, les Feature Flags ou même un simple équilibreur de charge. L'essentiel est une architecture correcte.
\n\nArchitecture d'un déploiement Canary pour une application .NET
\nImaginons que nous ayons une API web ASP.NET Core qui traite des commandes. Nous voulons déployer une nouvelle logique de calcul des remises. Au lieu de mettre à jour tous les pods en même temps, nous :
\n- \n
- Lançons deux versions du service : stable (v1) et canary (v2). \n
- Configurons un équilibreur de charge (par exemple, Nginx ou un Service Kubernetes) pour que 95 % du trafic aille vers v1 et 5 % vers v2. \n
- Ajoutons un en-tête HTTP
X-Canary: truedans les réponses de la version canary pour l'identification. \n - Collectons des métriques (code 200/500, latence, nombre de commandes). \n
- Si en 30 minutes il n'y a pas plus d'erreurs que sur v1, nous augmentons le poids du canary à 50 %, puis à 100 %. \n
Implémentation en C# : du simple au complexe
\n\nMéthode 1 : Canary via les en-têtes HTTP et un équilibreur de charge
\nLa méthode la plus simple consiste à utiliser une couche middleware dans ASP.NET Core qui marque les requêtes. Mais d'abord, regardons à quoi ressemble le code qui distingue la version canary.
\n// Startup.cs ou Program.cs\npublic class CanaryMiddleware\n{\n private readonly RequestDelegate _next;\n private readonly string _version;\n\n public CanaryMiddleware(RequestDelegate next, string version)\n {\n _next = next;\n _version = version;\n }\n\n public async Task InvokeAsync(HttpContext context)\n {\n // Ajout d'un en-tête pour identifier la version\n context.Response.Headers.Add("X-App-Version", _version);\n await _next(context);\n }\n}\n\n// Enregistrement\napp.UseMiddleware<CanaryMiddleware>("v2-canary");\n\nMaintenant, au niveau de l'équilibreur de charge (par exemple, Nginx), nous décidons quel pourcentage de trafic envoyer vers le pod canary :
\nupstream backend {\n server app-stable:5000 weight=95;\n server app-canary:5000 weight=5;\n}\n\nAvantages : simplicité. Inconvénients : pas de contrôle logiciel, difficile de faire des tests A/B par utilisateur.
\n\nMéthode 2 : Feature Flags en C#
\nUne approche plus flexible consiste à utiliser des feature flags (drapeaux de fonctionnalité). Vous activez la nouvelle logique uniquement pour un groupe spécifique d'utilisateurs. ASP.NET Core offre un support intégré :
\n// Installez le package Microsoft.FeatureManagement.AspNetCore\n// Ajoutez dans Program.cs\nbuilder.Services.AddFeatureManagement();\n\n// Définissez le drapeau dans appsettings.json\n{\n "FeatureManagement": {\n "NewDiscountLogic": false\n }\n}\n\n// Utilisez dans le contrôleur\n[ApiController]\n[Route