structural-engineering-and-design
Comment passer de l'architecture monolithique à l'architecture sans serveur sans couture
Table of Contents
Comprendre le changement
Les architectures monolithiques sont depuis longtemps la solution par défaut pour les applications de construction, regroupant toutes les logiques, l'accès aux données et l'interface utilisateur en une seule base de code couplée étroitement. Bien que cette approche simplifie le développement initial et le déploiement, elle crée des frictions importantes à mesure que les applications grandissent. Chaque changement nécessite la reconstruction et le redéploiement de l'ensemble de l'unité, l'échelle est grossière (vous devez faire une échelle à l'ensemble de l'application même si un seul composant est sous charge), et la vitesse du développeur ralentit au fur et à mesure que la base de code devient enchevêtrée.
Au lieu de gérer des serveurs ou des conteneurs toujours sur le serveur, vous déployez des fonctions individuelles qui fonctionnent dans des conteneurs de calcul apatrides, déclenchées par des événements tels que des requêtes HTTP, des modifications de base de données ou des messages de file d'attente de messages. Le fournisseur de cloud gère toutes les prestations d'infrastructure, l'échelle et la maintenance.
La transition du monolithique au sans serveur n'est pas un simple facteur; c'est un changement fondamental dans la façon dont vous concevez, construisez et exploitez des logiciels.
Pourquoi passer à sans serveur ?
Au-delà des avantages majeurs de l'évolutivité et de l'efficacité économique, sans serveur offre plusieurs avantages structurels qui s'attaquent directement aux points de douleur des monolithes:
- Écaillage de la taille générale. Dans un monolithe, les pics d'un module forcent l'application entière à l'échelle, gaspillant les ressources.
- Reduit les frais généraux opérationnels[ Aucun correctif serveur, planification de la capacité ou surveillance de disponibilité pour des cas individuels. Le fournisseur de cloud absorbe ce fardeau.
- ] On peut développer, tester et déployer de petites fonctions indépendantes par des équipes distinctes sans goulots d'étranglement de coordination.
- Paiement par utilisation. Les fonctions Idle sont sans coût, ce qui est particulièrement utile pour les charges de travail variables ou imprévisibles.
- Isolation de la faille par construction. Une défaillance d'une fonction ne se produit pas en cascade à d'autres, contrairement à un monolithe où une seule fuite de mémoire peut entraîner la perte de tout le service.
Avant de commencer : évaluez votre architecture actuelle
Une évaluation approfondie prévient le désastre. Commencez par cartographier votre monolithe existant pour comprendre sa structure, ses dépendances et ses points de douleur.
Analyse de la dépendance et du couplage
Utilisez des outils d'analyse statique (p. ex. générateurs de graphiques de dépendance) et de profilage d'exécution pour identifier un couplage serré entre les modules. Cherchez des schémas de base de données partagés, des variables globales et des appels de services codés en dur.
Identifier les candidats appropriés pour la première migration
Les candidats idéaux sont apatrides, ont des limites clairement définies et gèrent des fonctionnalités qui sont logiquement indépendantes. Les premières cibles communes sont les suivantes :
- Services de notification par courriel
- Pipelines de traitement d'images ou de fichiers
- Transformation des données et rapports sur les emplois
- Adaptateurs d'intégration API tiers
Évitez de déplacer des opérations d'état, des processus à long terme ou des composants avec des schémas d'accès à base de données profonds jusqu'à ce que vous ayez établi des modèles de traitement de données pour sans serveur.
Définir les critères de réussite
Définir des objectifs mesurables : réduire le temps de déploiement de X pour cent, réduire les coûts d'infrastructure de Y, réduire les taux d'erreur dans la fonction migrée ou améliorer la latence pour les utilisateurs finaux.
Stratégies de décomposition efficaces
La rupture d'un monolithe en fonctions sans serveur n'est pas la même chose que l'extraction de microservices. Les fonctions sans serveur sont encore plus granulaires.
Dessin de la figure de l'étrangleur
Le modèle de figuier strangler, popularisé par Martin Fowler, vous permet de remplacer progressivement la fonctionnalité monolithe par de nouveaux services alors que l'ancien système reste opérationnel. Vous interceptez les appels à un paramètre monolithe spécifique et les acheminez vers une nouvelle fonction sans serveur. Une fois la fonction prouvée, vous pouvez déclasser le code original. Cette approche minimise les risques et permet une livraison continue.
Conception de domaine et contextesoundés
Utilisez la conception par domaine (DDD) pour identifier les contextes délimités dans votre monolithe. Chaque contexte délimité représente un domaine cohérent de logique d'affaires avec son propre modèle de données. Extraire des contextes entiers comme services sans serveur. Cela réduit le coût de la synchronisation des données et maintient les règles d'affaires encapsulées.
Extraction par événement
Si votre monolithe émet des événements (ou vous pouvez ajouter des crochets d'événements), vous pouvez extraire des fonctionnalités comme des fonctions sans serveur pilotées par des événements. Par exemple, remplacer un appel synchrone pour envoyer un email de bienvenue par une fonction qui écoute un événement --user.created.
Plan de migration étape par étape
Une migration réussie se déplace pièce par pièce, avec des portes de validation à chaque étape.
1. Établir une infrastructure parallèle
Configurez votre plateforme sans serveur (AWS Lambda, Azure Functions, Google Cloud Functions) à côté de votre monolithe existant. Configurez le réseau de manière à ce que les deux systèmes puissent communiquer (par exemple via VPC peering, des terminaux privés ou une passerelle API partagée).
2. Créer une passerelle d'API comme une façade
Utilisez une passerelle API cloud (comme AWS API Gateway ou Azure API Management) pour faire face à votre monolithe et à vos nouvelles fonctions sans serveur. Initialement, la passerelle conduit tout le trafic vers le monolithe. Lorsque vous migrez chaque point d'arrêt, vous changez le routage pour pointer vers la nouvelle fonction. La passerelle impose une authentification cohérente, limite le taux et enregistre à travers les deux mondes.
3. Migrer les fonctions des apatrides d ' abord
Commencez par les candidats à faible risque identifiés plus tôt.
- Écrivez une nouvelle fonction sans serveur qui reproduit le comportement exact du module monolith.
- Ajoutez un drapeau de fonction ou une règle de routage qui envoie un petit pourcentage de trafic à la nouvelle fonction.
- Comparer les sorties, les latences et les taux d'erreur par rapport à la base de référence du monolithe.
- Augmentez progressivement le trafic jusqu'à ce que la fonction traite 100% des demandes, puis désactivez le code original.
4. Gérer l'état et les données
L'apatridie est un principe fondamental de l'absence de serveur, mais votre application a presque certainement besoin de données persistantes.
- Externaliser l'état vers les bases de données gérées. Utilisez AWS DynamoDB, Azure Cosmos DB ou Google Cloud Firestore. Ces bases de données s'échellent de façon indépendante et s'intègrent nativement aux fonctions sans serveur.
- Adoptez éventuellement la cohérence. Lorsque vous divisez une base de données monolithe en plusieurs magasins, vous perdez des transactions ACID dans tous les contextes.
- Utilisez un pipeline de saisie de données de changement (CDC) Des outils comme Debezium peuvent diffuser les changements de votre base de données monolithe vers des fonctions sans serveur, ce qui permet une migration progressive de l'accès aux données.
5. Migrer les emplois de base et les tâches planifiées
Les monolithes exécutent souvent des tâches cron ou des processus par lots. Remplacez-les par des fonctions sans serveur programmées (AWS EventBridge Scheduler, Azure Timer Trigger, Google Cloud Scheduler). Assurez-vous que les réticulations ne causent pas de duplication du traitement.
6. Mettre en oeuvre des plans d'essais et de rétrogradation de bout en bout
Chaque étape de migration doit être réversible. Gardez l'ancien chemin de code en vie jusqu'à ce que vous soyez certain que la version sans serveur fonctionne correctement. Utilisez les versions canari ou les modèles de déploiement bleu-vert.
Choisir la plate-forme sans serveur
Les principaux fournisseurs de cloud offrent des offres sans serveur matures, mais elles diffèrent en termes d'écosystème, de support linguistique de programmation et de nuances de prix.
- AWS Lambda (avec API Gateway, EventBridge, SQS, S3 triggers) – le meilleur pour les applications déjà sur AWS. Supporte Node.js, Python, Java, Go, Ruby, .NET, et les runtimes personnalisés. La latence de démarrage à froid est d'environ 200 à 500ms pour la plupart des runtimes; la concurrence fournie peut l'atténuer.
- Fonctions d'Azur – s'intègre étroitement aux services d'azure (Blob Storage, Service Bus, Cosmos DB). Offre des fonctions durables pour l'orchestration.
- Google Cloud Functions (maintenant en charge de Cloud Run pour les fonctions conteneurisées) – déploiement simple, intégration facile avec Firebase et BigQuery. Bon pour les applications événementielles et les pipelines de données.
- Cloudflare Workers – fonctionne au bord, sous--10ms commence à froid, mais avec des limites sur le temps d'exécution (30 secondes).Idéal pour les passerelles API et le traitement léger.
Évaluer chacun en fonction de vos compétences existantes, de vos exigences de conformité (résidence des données, certifications) et du coût total de la propriété en tenant compte du volume de la demande et de la durée d'exécution.
Meilleures pratiques pour une transition sans heurts
Maintenir des contrats clairs
Définir les contrats API (OpenAPI ou GraphQL) pour chaque fonction. Cela permet une évolution indépendante et permet aux équipes de travailler en parallèle. Utilisez la validation de schéma dans votre passerelle API pour faire appliquer les contrats.
Automatiser tout
L'infrastructure comme code (AWS CDK, Terraform, Pulumi) est essentielle pour les serveurs sans. Automatiser les déploiements, les tests et les retours. Utilisez les pipelines CI/CD qui déploient des fonctions indépendamment.
Sécurité d'abord
Appliquer les rôles IAM les moins privilégiés à chaque fonction. Appliquer le chiffrement des données au repos et en transit. Utiliser les gestionnaires de secrets (AWS Secrets Manager, Azure Key Vault) au lieu de variables d'environnement pour la configuration sensible. Mettre en œuvre la validation des demandes et limiter le taux au niveau de la passerelle.
Compétences d'équipe et esprit d'équipe
Les développeurs habitués aux monolithes ont souvent des difficultés avec la granularité fonctionnelle, la gestion de l'état et le débogage des systèmes distribués.Investir dans la formation : conception événementielle, outils d'observation (tractage distribué, logarithme) et stratégies de test pour les sans serveurs.
Pièges fréquents à éviter
- ]Les surprises de latence de démarrage à froid Les fonctions qui sont rarement invoquées peuvent prendre quelques secondes pour démarrer.
- Lock-in de Vendor Les cadres sans serveur sont souvent fortement liés aux services d'un fournisseur de cloud. Code spécifique du fournisseur d'abstract ou abstract en utilisant les objets événement/context de fonction et en conservant la logique d'affaires dans les fonctions pures.
- ] Des coûts peu élevés par demande peuvent s'additionner si vous avez des fonctions à haut débit avec des temps d'exécution longs. Modélisez votre charge de travail prévue (demandes par seconde, durée moyenne, mémoire attribuée) en utilisant la calculatrice de prix du fournisseur , avant de vous engager.
- Négligence d'observation. Un journal d'application monolithe est simple : vérifiez un serveur. Avec des centaines de fonctions, vous avez besoin de log centralisé, de tableaux de bord métriques et de tracage distribué. Configurez ces outils dès le premier jour, et non après que des problèmes se posent. OpenTelemetry est un bon choix de fournisseurs neutres.
- Attentir une réécriture big-bang. Le mode de défaillance le plus commun. Résistez à l'envie de réécrire tout le monolithe à la fois. La migration progressive réduit les risques, préserve la continuité des activités et permet à votre équipe d'apprendre des erreurs précoces.
Surveillance et observabilité dans le monde nouveau
Les systèmes sans serveur génèrent beaucoup plus de données que les monolithes. Implémenter ces couches :
- Logage structuré Chaque fonction doit afficher des journaux JSON avec des identifiants de corrélation, des identifiants de requête et une version de fonction. Centraliser les journaux dans un outil comme les journaux CloudWatch, Azure Log Analytics ou une solution tierce (Datadog, Sumo Logic).
- Retraçage distribué Utilisez AWS X-Ray, Azure Application Insights, ou Google Cloud Trace pour visualiser les requêtes de bout en bout au fur et à mesure qu'elles passent par plusieurs fonctions et services gérés.
- Surveiller le nombre d'invocations, le taux d'erreur, la durée, les événements throttisés et le coût par fonction. Régler les alertes pour les anomalies. Considérer les mesures d'affaires comme les réussites de la commande, et pas seulement les erreurs techniques.
- Utilisez des outils d'explorateur de coûts en nuage ou des plateformes tierces (CloudHealth, Vantage) pour suivre les dépenses par fonction et par équipe.
Considérations opérationnelles à long terme
Après la migration, le modèle opérationnel change de façon significative. Il n'y a pas de serveurs à corriger, mais vous devez gérer :
- Versions de fonction et alias Utilisez des déploiements canari pour déployer de nouvelles versions de fonction progressivement. Gérez les alias (p. ex., -PRODUCTION, -STAGING) pour pointer vers des versions stables.
- Limites de devises Chaque compte a une limite de concordance régionale par fonction. Planifiez les pics de trafic en demandant des augmentations à l'avance.
- Taguage de démarrage à froid Revoir régulièrement l'allocation de la mémoire de fonction (qui affecte également l'allocation CPU) et les choix d'exécution. Par exemple, les démarrages à froid de Python sont plus lents que Node.js. Utilisez Lambda SnapStart pour les fonctions Java ou la concordance prévue pour les chemins critiques.
- Les défis de cohérence des données. Finalement, les systèmes cohérents nécessitent une conception d'expérience utilisateur prudente.
Conclusion
La transition d'une architecture monolithique à une architecture sans serveur n'est pas un projet unique mais un parcours continu d'amélioration progressive. Il faut repenser la conception des applications, adopter de nouvelles pratiques opérationnelles et investir dans l'observation et l'automatisation. Le paiement – l'évolutivité générale, la réduction des frais généraux opérationnels et la livraison plus rapide des fonctionnalités – est important pour les organisations qui abordent la migration méthodiquement.
Pour plus de détails, consultez la documentation originale StranglerFigModèle de demande de Martin Fowler, examinez la documentation AWS Lambda et considérez le Serverless Framework pour l'automatisation du déploiement multi-fournisseurs.