Be Software Architecture Wise
Be Wise Apps

Read in English · Leer en español · Auf Deutsch lesen

Section 1.3 sur 1.8 · Débutant · 19 min de lecture

Pourquoi l’architecture compte : coût du changement, qualité, risques et échecs réels

Leçon vidéo

5 min · narré en anglais, avec sous-titres
Écouter seulement (audio)
Lire la transcription

Pourquoi une équipe, un product owner ou un directeur financier devraient-ils se soucier de l’architecture, plutôt que des seules fonctionnalités ? Cette leçon répond à cette question, avec trois cas réels.

Imaginez deux cuisines qui préparent la même carte. Dans l’une, les postes sont disposés de sorte que les cuisiniers se croisent rarement. Dans l’autre, le seul réfrigérateur se trouve derrière le lave-vaisselle. Lors d’une soirée calme, les deux servent les mêmes plats. Mais un samedi de grande affluence, ou quand la carte change, la seconde cuisine se bloque. Le logiciel, c’est pareil. Les fonctionnalités peuvent sembler identiques, mais l’agencement des parties détermine la rapidité, la fiabilité et le coût du système, et à quel point il est pénible de le modifier.

Des qualités comme les performances, la disponibilité, la sécurité et le coût sont émergentes. Elles naissent de la façon dont les parties sont agencées et interagissent, et non d’un morceau de code en particulier. Par exemple, si l’étape de paiement fait cinq appels successifs à des services disponibles chacun quatre-vingt-dix-neuf virgule neuf pour cent du temps, la chaîne ne peut pas faire mieux qu’environ quatre-vingt-dix-neuf virgule cinq pour cent. Les probabilités se multiplient. Ajouter une file d’attente ou un cache change ce calcul, et pourtant aucun de ces changements n’est visible à l’intérieur d’une fonction. Les deux sont architecturaux.

La structure régit aussi le coût du changement, et l’essentiel du coût d’un système qui réussit vient après sa première mise en production. L’hypothèse de l’endurance de la conception, formulée par Martin Fowler, décrit cet effet. Une équipe qui prête peu d’attention à la structure livre souvent plus vite au début. Mais l’enchevêtrement ralentit chaque changement, et une équipe qui a investi dans la structure finit par la dépasser. Fowler parle d’hypothèse parce que c’est difficile à mesurer, et suggère que le gain arrive généralement en quelques semaines plutôt qu’en quelques mois. Ce ralentissement, ce sont les intérêts de la dette technique, que traite la section un point sept.

Voici un exemple commenté, avec des chiffres illustratifs. Une boutique en ligne stocke les montants sous forme de nombres à virgule flottante, qui ne peuvent pas représenter exactement de nombreuses valeurs décimales, si bien que les totaux sont parfois faux d’un penny. Le premier mois, deux développeurs pourraient passer au stockage en pence entiers en une demi-journée environ. Cela représente environ trois cents livres. En troisième année, trente-cinq services manipulent des montants, cent vingt colonnes de base de données les stockent, il existe deux cents millions d’anciennes lignes de commandes, et quatre systèmes partenaires les échangent. Désormais, le même changement demande environ cent quatre-vingt-quinze jours-personne. Cela représente environ cent dix-sept mille livres, plusieurs centaines de fois le coût initial. La décision elle-même n’a jamais changé de taille. Ce qui a grandi, c’est tout ce qui a été construit par-dessus.

L’architecture contient ou amplifie aussi les risques. Le premier août 2012, la société de trading Knight Capital a perdu plus de quatre cent soixante millions de dollars en quarante-cinq minutes de négociation environ. Son routeur d’ordres recevait des ordres marqués d’un flag. Un nouveau code réutilisait ce flag, qui des années plus tôt activait une ancienne fonction appelée Power Peg. Le code de Power Peg était toujours là. Le nouveau code a été déployé à la main sur les huit serveurs du routeur. Sept l’ont reçu et ont traité les ordres normalement. Mais un technicien n’a pas copié le code sur le huitième serveur. Quand le flag a été activé, ce serveur a exécuté Power Peg. Il a envoyé des millions d’ordres non voulus, et reçu plus de quatre millions d’exécutions. Aucun second technicien n’a vérifié le déploiement, et rien ne contrôlait que tous les serveurs concordaient. Du vieux code encore accessible, un flag à deux significations et une mise en production non vérifiée sont des décisions de structure et de processus, pas une ligne fautive.

Quand la place de marché américaine de l’assurance santé, HealthCare point gov, a ouvert en octobre 2013, de nombreuses personnes n’ont pas pu créer de compte. Les auditeurs du gouvernement ont constaté qu’elle avait été lancée sans vérifier qu’elle satisfaisait à ses exigences de performances. Plusieurs prestataires ont construit des parties distinctes, et personne n’a testé l’ensemble assemblé sous une charge réaliste. La capacité est une propriété du système entier : il faut donc que quelqu’un soit responsable de l’ensemble. En 2023, l’équipe Prime Video d’Amazon a fait passer un service de supervision d’étapes serverless distribuées à un processus unique, en transmettant les données en mémoire. Elle a indiqué que les coûts d’infrastructure avaient baissé de plus de quatre-vingt-dix pour cent. Cela ne veut pas dire que les monolithes l’emportent sur le serverless. La première conception convenait à une charge de travail initiale plus petite. L’architecture est une question d’adéquation, pas de mode : demandez-vous ce dont la charge de travail, l’équipe et le budget ont besoin.

Voilà pourquoi l’architecture compte. La section complète raconte chaque cas plus en détail et montre comment les équipes, la communication et les estimations dépendent de la structure. Ensuite, dans la section un point quatre, nous verrons ce que fait réellement un architecte. À très vite.

Ce qu’il faut savoir

Les décisions qu’il coûte cher de rater

La section 1.1 a défini l’architecture comme l’ensemble des structures et des décisions significatives qui façonnent un système, l’importance d’une décision se mesurant au coût du changement. Cette section pose la question pratique qui s’ensuit : et alors ? Pourquoi une équipe, un product owner ou un directeur financier devraient-ils se soucier de l’architecture, plutôt que simplement des fonctionnalités ?

La réponse courte est que l’architecture détermine, plus que tout autre facteur technique, ce à quoi le système ressemblera : à quel point il sera rapide, fiable, sécurisé, bon marché à exploiter et surtout facile à modifier. Les fonctionnalités sont ce que fait un système. L’architecture détermine à quel point il le fait bien et ce qu’il en coûtera de faire autre chose l’an prochain. Beaucoup de grands échecs logiciels et beaucoup de succès coûteux remontent à une poignée de décisions structurelles.

L’architecture détermine les attributs de qualité

Un attribut de qualité est une propriété mesurable de la façon dont un système fait son travail : performances, disponibilité, sécurité, modifiabilité, scalabilité, utilisabilité, efficacité des coûts, et d’autres encore. Le chapitre 2 les précise. Le point essentiel ici est que la plupart des attributs de qualité sont émergents : ils naissent de la façon dont les parties sont agencées et interagissent, et non d’un morceau de code en particulier.

Prenons la disponibilité. Si l’étape de paiement d’une boutique en ligne doit faire cinq appels synchrones successifs à des services disponibles chacun 99,9 % du temps, la chaîne dans son ensemble ne peut pas être disponible à plus de 99,5 % environ, aussi bien écrit que soit chaque service, car les probabilités se multiplient. Ajouter une file d’attente pour que certaines de ces étapes aient lieu plus tard, ou mettre des résultats en cache pour que certains appels deviennent inutiles, change le calcul. Aucun de ces changements n’est visible à l’intérieur d’une fonction ; tous deux sont architecturaux. Les performances, la sécurité et le coût se comportent de la même façon. Une page de connexion sécurisée ne rend pas un système sécurisé si un service interne sans authentification est accessible depuis internet.

Les fonctionnalités, en revanche, sont généralement assez indépendantes de la structure. Vous pouvez mettre en œuvre les mêmes fonctionnalités d’une application bancaire sous forme d’une seule unité déployable ou de cinquante services ; les utilisateurs voient les mêmes boutons. Ce qui change, c’est tout le reste : la rapidité avec laquelle un correctif peut être mis en production, ce qui se passe quand une partie tombe en panne, le nombre d’ingénieurs que le système peut absorber, et le montant de la facture cloud.

Coût et rapidité du changement

L’essentiel du coût d’un système qui réussit intervient après sa première mise en production, à mesure qu’il est modifié pour répondre à de nouveaux besoins. La structure compte donc surtout parce qu’elle régit le coût de chaque changement futur. Dans un système bien structuré, une modification des règles fiscales touche un seul module. Dans un système enchevêtré, elle en touche vingt, qui demandent chacun des tests et de la coordination.

L’hypothèse de l’endurance de la conception (design stamina hypothesis) de Martin Fowler (2007) décrit cet effet. Une équipe qui prête peu d’attention à la structure interne livre souvent plus vite au début. Avec le temps, l’enchevêtrement accumulé ralentit chaque changement, et une équipe qui a investi dans la structure finit par la dépasser. Fowler parle d’hypothèse parce qu’elle est difficile à mesurer rigoureusement, et il suggère que le croisement intervient généralement en quelques semaines plutôt qu’en quelques mois. Ce ralentissement correspond aux intérêts de la dette technique, que traite la section 1.7.

L’hypothèse de l’endurance de la conception

Graphique conceptuel des fonctionnalités cumulées dans le temps pour un système bien structuré et un système mal structuréDuréeFonctionslivréesrentabilitéPeu d’attention à la structureStructure délibéréerapide au début
Une esquisse conceptuelle d’après Martin Fowler : prêter moins d’attention à la structure va plus vite au début, mais une structure délibérée maintient le rythme de livraison.

Exemple commenté

Exemple commenté : le coût d’une décision dans le temps

Une boutique en ligne stocke les montants sous forme de nombres à virgule flottante. L’arithmétique à virgule flottante ne peut pas représenter exactement de nombreuses valeurs décimales (0,1 + 0,2 ne fait pas exactement 0,3), si bien que les totaux diffèrent parfois d’un penny de ce qu’attendent les comptables. Les chiffres ci-dessous sont des hypothèses illustratives, et non des données du secteur, choisies pour montrer comment le coût du changement augmente.

Mois 1 : décider autrementDeux développeurs conviennent de stocker plutôt des unités monétaires mineures entières (des pence). Effort : environ une demi-journée. Coût, à un tarif supposé de £600 par jour-personne : environ £300.
Année 3 : ce qui a été construit sur la décision35 services manipulent des montants ; 120 colonnes de base de données les stockent ; 200 millions de lignes de commandes historiques ; 4 intégrations partenaires (prestataire de paiement, entrepôt, comptabilité, place de marché) les échangent.
Année 3 : modifications du code35 services à environ 3 jours-personne chacun pour modifier, tester et mettre en production = 105 jours-personne.
Année 3 : migration des donnéesConvertir les colonnes, migrer l’historique, rapprocher les totaux : environ 20 jours-personne, plus une fenêtre de maintenance planifiée.
Année 3 : coordination avec les partenaires4 partenaires à environ 10 jours-personne chacun, y compris leurs tests et les modifications de contrat = 40 jours-personne.
Année 3 : tests de bout en bout et rapprochement avec le service financierEnviron 30 jours-personne.
Année 3 : totalEnviron 195 jours-personne, soit à peu près £117 000, plus le risque d’erreurs pendant la migration et des mois de délai. C’est plusieurs centaines de fois le coût du mois 1.

La décision elle-même n’a jamais changé de taille. Ce qui a grandi, c’est tout ce qui a été construit par-dessus : code, données, partenaires et habitudes.

C’est pourquoi Ralph Johnson décrivait l’architecture comme les décisions que l’on aimerait pouvoir prendre correctement dès le début, et pourquoi les architectes recherchent les conventions de bas niveau à large portée.

Une autre stratégie consiste à rendre ces décisions moins coûteuses à inverser, par exemple en plaçant dès le départ toute la gestion des montants derrière un type ou une bibliothèque partagés, pour qu’un changement ultérieur reste local.

Risques, équipes, communication et estimation

Risques. C’est dans l’architecture que la plupart des risques techniques sont soit contenus, soit amplifiés. Une conception comportant un point de défaillance unique, une intégration non testée entre des parties construites indépendamment, ou une technologie non éprouvée en son cœur porte un risque qu’aucun codage soigneux ne supprime. Une grande partie du travail architectural relève de la gestion des risques : identifier ce qui pourrait très mal tourner et façonner la structure pour que cela ne puisse pas arriver, ou ne fasse que des dégâts limités si cela arrive.

Répartir le travail entre les équipes. Melvin Conway a observé en 1968 que les organisations qui conçoivent des systèmes tendent à produire des conceptions qui reflètent leurs propres structures de communication. C’est ce qu’on appelle aujourd’hui la loi de Conway, et elle joue dans les deux sens. Un système dont les parties ont des frontières claires et des interfaces étroites permet à plusieurs équipes de travailler en parallèle avec peu de coordination. Un système où tout dépend de tout oblige chaque équipe à assister à chaque réunion. L’architecture et la conception de l’organisation sont donc étroitement liées, comme l’explique la section du chapitre 3 sur la loi de Conway.

Communication. Une architecture donne aux personnes un vocabulaire commun et une carte commune. Les nouveaux ingénieurs apprennent le système plus vite, les chefs de produit comprennent pourquoi certaines demandes sont bon marché et d’autres coûteuses, et les équipes d’exploitation savent ce qui dépend de quoi pendant un incident.

Estimation et planification. La décomposition en parties connues rend l’estimation possible : un changement peut être rattaché aux composants qu’il touche, et chacun peut être estimé par l’équipe qui le connaît. Sans structure claire, les estimations sont des suppositions, car personne ne peut dire avec certitude jusqu’où un changement se propagera.

Étude de cas : Knight Capital, 1er août 2012

Knight Capital était l’un des plus grands teneurs de marché sur les actions américaines. Selon l’ordonnance de la Securities and Exchange Commission des États-Unis du 16 octobre 2013, au cours des 45 premières minutes de négociation du 1er août 2012, le routeur d’ordres automatisé de Knight (appelé SMARS) a envoyé des millions d’ordres non voulus sur le marché en traitant 212 petits ordres de particuliers. Il a reçu plus de 4 millions d’exécutions sur 154 titres, portant sur plus de 397 millions d’actions, et s’est retrouvé avec d’importantes positions non désirées. Knight a perdu plus de 460 millions de dollars US, a eu besoin d’un investissement extérieur d’urgence en quelques jours, et la SEC lui a ensuite infligé une amende de 12 millions de dollars US pour violation des règles d’accès au marché.

L’ordonnance de la SEC décrit le mécanisme. Des années plus tôt, Knight avait cessé d’utiliser une ancienne fonction appelée Power Peg, mais son code était resté dans le routeur et pouvait encore être déclenché : c’était du code mort qui n’était pas mort. En 2012, Knight a écrit du nouveau code pour un nouveau programme du NYSE, le Retail Liquidity Program, et ce nouveau code réutilisait un flag (indicateur) qui servait autrefois à activer Power Peg. Le nouveau code a été déployé manuellement sur les huit serveurs du routeur. Un technicien ne l’a pas copié sur l’un d’eux, aucun second technicien n’a vérifié le déploiement, et Knight n’avait aucune procédure écrite exigeant une telle vérification. Quand le flag a été activé, sept serveurs ont exécuté le nouveau code ; le huitième a interprété le flag comme « exécuter Power Peg » et a envoyé des ordres sans reconnaître qu’ils avaient déjà été exécutés. Des e-mails automatiques signalant un problème ont été envoyés avant l’ouverture du marché, mais personne n’y a donné suite.

Comment un seul serveur pas à jour a causé les pertes de Knight Capital

Routeur de Knight Capital : le nouveau code a atteint sept serveurs sur huit ; le huitième exécutait encore l’ancienne Power PegOrdres de particuliers marqués avecle flag réutilisé (prévu : nouveau code RLP)Routeur SMARS : huit serveurscode RLPneufcode RLPneufcode RLPneufcode RLPneufcode RLPneufcode RLPneufcode RLPneufvieux codePower PegOrdres enfants sans fin+ de 4 millions d’exécutionsen 45 minutes environExécution normalePas de second technicien pour revoir le déploiement ; aucun contrôle auto de la concordance des serveurs
Un flag réutilisé, un serveur pas à jour et aucune vérification du déploiement : la défaillance tenait à la structure et au processus, pas à une ligne de code isolée.

Il serait injuste de qualifier cela de simple bug de codage, et tout aussi injuste d’y voir une pure erreur d’exploitation. Les leçons architecturales portent sur la structure et la déployabilité : une fonctionnalité obsolète laissée accessible dans un système en production ; un même flag doté de deux significations dans différentes versions du code ; un processus de déploiement sans vérification automatique que tous les serveurs exécutaient la même version ; et, comme l’a souligné la SEC, des contrôles insuffisants pour limiter les dégâts une fois que quelque chose avait mal tourné. Chacune est une décision sur la façon dont le système est construit et mis en production, et non sur une ligne de code isolée.

Étude de cas : le lancement de HealthCare.gov, octobre 2013

HealthCare.gov, la place de marché fédérale américaine de l’assurance santé, a ouvert les inscriptions le 1er octobre 2013. De nombreuses personnes n’ont pas pu créer de compte ni terminer leur demande, et le site a subi des pannes pendant des semaines. Le Government Accountability Office (GAO) des États-Unis et l’Office of Inspector General (OIG) du Department of Health and Human Services (ministère de la Santé et des Services sociaux) ont ensuite enquêté, et leurs conclusions sont la meilleure source pour comprendre ce qui n’a pas fonctionné.

Le rapport du GAO de juillet 2014 (GAO-14-694) a constaté que les Centers for Medicare and Medicaid Services (CMS) avaient attribué des contrats avant que les exigences clés ne soient arrêtées, que les exigences n’avaient cessé de changer, que le contrôle était insuffisant et que les CMS avaient lancé le système sans vérifier qu’il satisfaisait à ses exigences de performances. Les engagements au titre du principal contrat de la place de marché sont passés de 56 millions de dollars US à plus de 209 millions de dollars US entre 2011 et début 2014. Un second rapport du GAO, en mars 2015 (GAO-15-238), a constaté que les systèmes n’avaient pas été entièrement testés avant le lancement, et que les problèmes au lancement comprenaient une planification de capacité insuffisante, des erreurs de codage et des fonctions prévues qui n’avaient pas été mises en œuvre. L’étude de cas de l’OIG de 2016 a désigné l’absence de leadership clair et la mauvaise coordination entre le travail sur les politiques publiques et le travail technique comme causes centrales. Après d’intenses travaux correctifs, le site a pu répondre à une forte demande des consommateurs en deux mois environ.

L’histoire de HealthCare.gov relève surtout de la gestion de programme, mais sa leçon architecturale est directe. La place de marché a été construite par plusieurs prestataires sous forme de parties distinctes qui devaient fonctionner ensemble, dont un hub de données connecté à d’autres agences fédérales, et personne n’a vérifié de bout en bout, sous une charge réaliste, que l’ensemble assemblé atteignait ses objectifs de capacité et de performances. Les attributs de qualité comme la capacité sont des propriétés du système entier : ils ne peuvent donc être garantis que par quelqu’un qui est responsable de la structure du système entier et qui le teste comme un tout.

Étude de cas : Prime Video, ou l’architecture comme adéquation et non comme mode

En mars 2023, un ingénieur de l’équipe Video Quality Analysis d’Amazon Prime Video a publié sur le blog Prime Video Tech un billet consacré à un service qui surveille les flux vidéo pour y détecter des défauts de qualité. La première version avait été construite à partir de composants serverless distribués : AWS Step Functions orchestrait les étapes et des fonctions AWS Lambda effectuaient le travail, les images vidéo intermédiaires passant d’une étape à l’autre par le stockage Amazon S3. L’équipe a indiqué que cette conception se heurtait à une limite de scalabilité stricte à environ 5 % de la charge prévue et aurait été trop coûteuse à pleine échelle, en grande partie à cause des frais d’orchestration par étape et des nombreuses requêtes de stockage.

L’équipe a regroupé les étapes de conversion des médias et de détection des défauts dans un processus unique s’exécutant dans des conteneurs sur Amazon ECS, en faisant passer les images en mémoire plutôt que par le stockage, et a assuré la montée en charge en exécutant davantage de copies de ce processus. Le billet indiquait que les coûts d’infrastructure avaient baissé de plus de 90 % et que le service pouvait monter davantage en charge. Le billet a été largement partagé sous le titre « Amazon abandonne les microservices », ce qu’il ne disait pas : le changement concernait un seul service, et l’auteur notait que les microservices et les composants serverless fonctionnent bien à grande échelle, mais que le choix entre eux et un monolithe doit se faire au cas par cas.

Le service de supervision de Prime Video, avant et après

Service de supervision de Prime Video avant et après : étapes serverless distribuées passant les données par le stockage, puis un seul processus les passant en mémoireAvant : serverless distribuéAprès : un processus répliquéOrchestration Step FunctionsConversion médiaS3 : images intermédiairesDétect. de défautsNotificationtransition d’état par étapeProcessus unique (conteneur)Conversion médiaen mémoireDétect. de défautsNotificationdupliqué pour monter en charge
Les mêmes étapes, regroupées : faire passer les données en mémoire au sein d’un seul processus a supprimé les coûts d’orchestration par étape et de stockage.

La leçon n’est pas que les monolithes l’emportent sur le serverless. C’est que l’architecture est une question d’adéquation. La conception serverless était rapide à construire et appropriée pour une charge de travail initiale plus petite. Quand la caractéristique déterminante de cette charge (de très gros volumes de données transmis entre les étapes pour chaque seconde de chaque flux) est devenue prépondérante, une structure qui faisait transiter ces données sur le réseau à de nombreuses reprises n’était plus adaptée, et une autre structure convenait mieux. Un bon architecte se demande ce dont la charge de travail, l’équipe et le budget ont besoin, et non ce qui est à la mode.

Vérifiez votre compréhension

Pourquoi un service bien écrit peut-il quand même faire partie d’un système peu fiable ?

Parce que la disponibilité naît de la façon dont les services dépendent les uns des autres. Une chaîne d’appels synchrones multiplie les probabilités de défaillance, si bien que l’ensemble peut être moins disponible que n’importe laquelle de ses parties.

Qu’est-ce qui faisait de la défaillance de Knight Capital un problème architectural plutôt qu’un simple bug ?

Du code obsolète accessible, un flag ayant deux significations selon les versions, et un déploiement manuel sans contrôle automatique de la concordance de tous les serveurs : autant de décisions de structure et de mise en production, et non une seule ligne fautive.

Quelle est la principale leçon du cas Prime Video ?

Qu’une architecture doit être adaptée à sa charge de travail et à son contexte. Une conception adaptée à une certaine échelle et à un certain profil de données peut devenir mal adaptée, et changer de structure peut transformer les coûts.

Pourquoi le coût de la remise en cause d’une décision augmente-t-il avec le temps ?

Parce que de plus en plus de code, de données stockées, d’intégrations, de partenaires et d’habitudes en viennent à en dépendre : la changer signifie donc les changer tous.

Suivant · 1.4Le rôle de l’architecteCe que font réellement les architectes au quotidien, les huit attentes décrites par Richards et Ford, les types d’architectes, l’étendue face à la profondeur, et la question de savoir si les architectes doivent encore écrire du code.Continuer →

Sources et lectures complémentaires

Une question sur cette section ? ArchitectBot, l’assistant d’étude IA du cours, répond d’abord à partir du cours.

Demander : « Comment expliquer à un chef de produit pourquoi modifier maintenant notre modèle de données des commandes coûtera tellement plus cher qu’il y a un an ? »