Read in English · Leer en español · Auf Deutsch lesen
Section 11.3 sur 11.8 · Avancé · 27 min de lecture
Fonctions d’aptitude et architecture évolutive
Leçon vidéo
5 min · narré en anglais, avec sous-titresÉcouter seulement (audio)
Lire la transcription
Une évaluation est un instantané. Dès le lendemain, chaque modification peut défaire discrètement une décision sur laquelle elle s’appuyait. Dans cette leçon, vous allez découvrir comment les fonctions d’aptitude vérifient ces décisions automatiquement et en continu.
Le tableau de bord d’une voiture comporte des voyants d’alerte pour ce qui ne doit jamais mal tourner sans qu’on le remarque : pression d’huile, température du moteur, freins. Vous n’attendez pas la révision annuelle pour découvrir que le moteur a surchauffé en mars. Une fonction d’aptitude est un voyant d’alerte pour une architecture logicielle. L’équipe décide quelles qualités comptent vraiment, comme la rapidité avec laquelle une commande est confirmée, et écrit une vérification automatique pour chacune. Ces vérifications s’exécutent à chaque modification du logiciel. Quand l’une d’elles échoue, la modification est arrêtée ou quelqu’un est alerté, tant que le problème est encore petit.
Le terme vient du livre Building Evolutionary Architectures, de Neal Ford et ses coauteurs. Une fonction d’aptitude est tout mécanisme qui fournit une évaluation objective d’une caractéristique d’architecture. Tout mécanisme : un test unitaire, un test de charge, une sonde de supervision, une expérience de chaos, voire une revue manuelle planifiée. Objective : le résultat ne doit pas dépendre de la personne qui l’exécute. Le sentiment que le code est bien structuré ne compte pas. Et une métrique décrit, mais une fonction d’aptitude décide. En enfreindre une impose un choix conscient : corriger le code, ou changer la règle et consigner pourquoi.
Voici l’anatomie de l’une d’elles. Partez d’une caractéristique, comme la latence des commandes, et d’une façon de la mesurer : les quatre-vingt-quinzième et quatre-vingt-dix-neuvième percentiles, à cent commandes par seconde. Le seuil vient directement de la mesure de la réponse du scénario : une seconde et demie, et trois secondes. La vérification est un test de charge dans le pipeline, et l’action, quand le seuil est dépassé, consiste à faire échouer le build. Une fonction d’aptitude doit échouer bruyamment, et non remplir un tableau de bord que personne ne lit. En dessous, elle remonte à son scénario source. Et elle a un responsable, une date de revue et une justification consignée dans un enregistrement de décision d’architecture, ou ADR.
Les fonctions d’aptitude s’exécutent tout au long du pipeline de livraison. Les vérifications atomiques testent une seule caractéristique ; les vérifications holistiques en testent plusieurs ensemble. À chaque build viennent des vérifications atomiques, rapides et peu coûteuses : règles de dépendance, vérification des cycles, limites de complexité et dépendances présentant des vulnérabilités connues. À l’étape de test viennent des vérifications holistiques plus lentes : un test de charge avec des seuils de percentiles, des vérifications de schémas et de contrats, et un test de failover. Au stade du canari, le taux d’erreur et la latence de la nouvelle version sont comparés à ceux de l’ancienne. Et en production, des vérifications continues s’exécutent en permanence : suivi des objectifs de niveau de service, ou SLO, commandes fictives, expériences de chaos et coût par commande. Les échecs et la dérive reviennent sous forme de nouveau travail, et souvent de nouvelles fonctions d’aptitude.
Maintenant, la plateforme transforme trois scénarios en fonctions d’aptitude. Premier scénario : à cent commandes par seconde, quatre-vingt-quinze pour cent des commandes sont confirmées en moins d’une seconde et demie, et quatre-vingt-dix-neuf pour cent en moins de trois. La fonction d’aptitude numéro un est un test de charge sur un environnement semblable à la production, chaque nuit et avant chaque mise en production. Elle échoue si l’un des percentiles dépasse son seuil, ou si plus de zéro virgule un pour cent des requêtes échouent. La seconde et demie est aussi répartie en budgets pour le réseau, la passerelle, les commandes, la tarification et les écritures en base de données, ce qui laisse cinq cent cinquante millisecondes de marge. Chaque service teste son propre budget, si bien qu’une régression est détectée là où elle est causée. Le deuxième scénario est la disponibilité du paiement. Chaque semaine, en staging, une expérience de chaos fait se bloquer le prestataire de paiement. Les commandes doivent quand même être acceptées comme en attente en moins de dix secondes, et toutes doivent être finalisées après le rétablissement. Troisième scénario : un nouvel éditeur de caisse devrait demander cinq jours de travail d’une personne, par l’ajout d’un seul adaptateur. Une règle de build empêche le code des restaurants et des commandes d’importer le kit logiciel d’un éditeur, si bien que le changement reste local. Chacune est consignée avec son scénario source, son seuil, son responsable, l’ADR qui l’explique et une date de revue.
Les fonctions d’aptitude sont la moitié de ce que ces auteurs appellent l’architecture évolutive : un changement guidé et incrémental selon de multiples dimensions. Les petites parties déployables et les pipelines rapides fournissent les incréments. Les fonctions d’aptitude fournissent le guidage. Commencez petit. Choisissez les trois à cinq caractéristiques les mieux classées dans l’arbre d’utilité, et écrivez une vérification fiable pour chacune. Une douzaine de vérifications dignes de confiance valent mieux qu’une centaine qui échouent au hasard. Pour un système existant, utilisez un effet cliquet. Consignez les violations d’aujourd’hui comme base de référence, ne bloquez que les nouvelles, et resserrez la base de référence à mesure que la dette est remboursée. Et gardez le pipeline rapide : vérifications atomiques à chaque build, et vérifications holistiques lourdes, comme les tests de charge de dix minutes, chaque nuit ou avant la mise en production.
La section complète traite des dimensions des fonctions d’aptitude et donne le code des trois vérifications. Ensuite, dans la section onze point quatre, nous verrons la gouvernance dans les organisations agiles. À très vite.
Ce qu’il faut savoir
- Une fonction d’aptitude architecturale est tout mécanisme qui fournit une évaluation objective d’une caractéristique d’architecture, idéalement automatisé et rattaché à un scénario d’attribut de qualité dont la mesure de la réponse devient le seuil.
- Les fonctions d’aptitude se classent selon qu’elles sont atomiques ou holistiques, déclenchées, continues ou temporelles, statiques ou dynamiques, automatisées ou manuelles, et intentionnelles ou émergentes ; un ensemble sain les combine.
- Les exemples typiques sont les règles de dépendance pour la structure, les tests de charge et les budgets de latence pour les performances, les analyses de vulnérabilités pour la sécurité, les expériences de chaos pour la résilience et les vérifications de compatibilité des schémas pour les données.
- L’architecture évolutive (Ford, Parsons, Kua et Sadalage) permet un changement guidé et incrémental selon de multiples dimensions ; les fonctions d’aptitude fournissent le guidage, et les petites unités déployables et les pipelines fournissent les incréments.
- Chaque fonction d’aptitude a besoin d’un responsable, d’une justification consignée et d’un seuil, et un échec impose une décision : corriger le code, ou changer la règle et consigner pourquoi.
- Commencez par quelques vérifications fiables pour les caractéristiques les plus prioritaires, appliquez aux systèmes existants un effet cliquet à partir d’une base de référence, et tenez les vérifications holistiques lentes à l’écart de chaque build.
De l’évaluation ponctuelle à la vérification continue
Une évaluation comme l’ATAM (section 11.1) est un instantané. Dès le lendemain, les développeurs commencent à modifier le système, et chaque modification peut défaire discrètement une décision sur laquelle l’évaluation s’appuyait : un import commode qui franchit une frontière de module, un appel synchrone supplémentaire sur le chemin de la commande, une bibliothèque qui présente une vulnérabilité connue. La section 1.7 a décrit le résultat : l’érosion, quand l’architecture est violée, et la dérive, quand elle est ignorée. Les revues périodiques en détectent une partie, avec des mois de retard. L’idée de cette section est de vérifier les décisions architecturales les plus importantes automatiquement et en continu, de la même façon que les tests unitaires vérifient le comportement.
Le terme vient de l’ouvrage de Neal Ford, Rebecca Parsons et Patrick Kua, Building Evolutionary Architectures (O’Reilly, 2017), dont la deuxième édition, avec Pramod Sadalage, est parue en novembre 2022. Ils l’ont emprunté au calcul évolutionnaire, où une fonction d’aptitude note la proximité d’une solution candidate avec l’objectif, afin que l’algorithme puisse conserver les meilleures variantes. En architecture, l’objectif est l’ensemble des caractéristiques que le système doit conserver pendant que tout le reste change.
Ce qu’est une fonction d’aptitude
La deuxième édition définit une fonction d’aptitude (fitness function) architecturale comme tout mécanisme qui fournit une évaluation objective de l’intégrité d’une ou de plusieurs caractéristiques d’architecture. Trois termes de cette définition font tout le travail. Tout mécanisme : un test unitaire, une règle d’analyse statique, un test de charge, une sonde de supervision, une expérience de chaos ou même une revue manuelle planifiée conviennent tous. Objective : le résultat ne doit pas dépendre de la personne qui l’exécute ; « le code semble bien structuré » n’est pas une fonction d’aptitude, « aucun paquet de la couche domaine n’importe le framework web » en est une. Caractéristique d’architecture : la vérification protège une qualité que l’architecture a pour raison d’être de fournir (performances, disponibilité, modifiabilité, sécurité, compatibilité des données), et non une règle métier, qui relève des tests ordinaires.
En pratique, une fonction d’aptitude utile possède quelques propriétés de plus. Elle est rattachée à une exigence, idéalement un scénario d’attribut de qualité dont la mesure de la réponse devient son seuil (section 2.3). Elle a un responsable qui décide de ce qui se passe quand elle échoue. Elle échoue bruyamment, en cassant un build ou en alertant la personne d’astreinte, plutôt qu’en alimentant un tableau de bord que personne ne lit. Et son seuil, ainsi que la raison de ce seuil, sont consignés, généralement dans un ADR, afin qu’une équipe ultérieure puisse distinguer une règle qui protège quelque chose d’important d’un chiffre arbitraire.
La section 3.8 a établi la distinction importante avec les métriques : une métrique décrit, une fonction d’aptitude décide. Une métrique de couplage sur un tableau de bord vous dit que la situation se dégrade ; une fonction d’aptitude encode une décision que l’équipe a déjà prise, si bien que l’enfreindre impose un choix conscient : corriger le code, ou changer la règle et consigner pourquoi.
Anatomie d’une fonction d’aptitude
Catégories de fonctions d’aptitude
Ford et ses coauteurs classent les fonctions d’aptitude selon plusieurs dimensions indépendantes. Cette classification est moins utile comme taxinomie que comme aide à la conception : se demander « celle-ci doit-elle être atomique ou holistique, déclenchée ou continue ? » révèle souvent une meilleure vérification que la première qui venait à l’esprit.
Dimensions des fonctions d’aptitude
| Dimension | Options | Signification | Exemple |
|---|---|---|---|
| Portée | Atomique ou holistique | L’atomique vérifie une caractéristique dans un seul contexte ; l’holistique vérifie plusieurs caractéristiques en interaction dans un contexte partagé | Atomique : aucun cycle entre paquets. Holistique : latence des commandes mesurée avec chiffrement, journalisation d’audit et cache tous activés |
| Moment d’exécution | Déclenchée, continue ou temporelle | La déclenchée s’exécute sur un événement comme un commit, un build ou un déploiement ; la continue s’exécute en permanence sur le système en production ; la temporelle se déclenche une fois un délai écoulé, pour rappeler de réexaminer quelque chose | Déclenchée : analyse des dépendances à chaque build. Continue : alerte sur le taux de consommation du SLO en production. Temporelle : faire échouer le build quand une version figée d’un framework a plus de 12 mois |
| Type de résultat | Statique ou dynamique | La statique compare à un seuil fixe ; la dynamique ajuste le seuil au contexte, par exemple à l’échelle | Statique : p95 inférieur à 1,5 s. Dynamique : le p95 peut monter à 2 s au-delà de 150 commandes/s, comme convenu pour les pics extrêmes |
| Mode d’exécution | Automatisée ou manuelle | L’automatisée est préférable ; certaines caractéristiques, comme les exigences légales ou d’utilisabilité, demandent encore des personnes, idéalement selon un calendrier | Manuelle : revue trimestrielle de l’accessibilité au regard des WCAG 2.2 AA |
| Planification | Intentionnelle ou émergente | Les intentionnelles sont conçues en amont à partir d’exigences connues ; les émergentes sont ajoutées à mesure que l’équipe apprend ce qui compte | Émergente : une vérification du retard des consommateurs (consumer lag) ajoutée après un incident |
Les vérifications holistiques méritent l’attention, car les qualités interagissent : les contrôles de sécurité ajoutent de la latence, le cache complique la fraîcheur des données, et un test atomique de chacun pris isolément peut réussir alors que la combinaison échoue. Les vérifications continues comptent, car certaines caractéristiques n’existent qu’en production : la latence réelle vécue par les utilisateurs, les modes de défaillance réels, le coût réel. Un portefeuille sain combine des vérifications rapides, atomiques et déclenchées dans le build avec un plus petit nombre de vérifications holistiques plus lentes avant la mise en production et des vérifications continues en production.
Où s’exécutent les fonctions d’aptitude
Les fonctions d’aptitude selon les qualités
La plupart des équipes commencent par la structure, parce que les vérifications structurelles sont peu coûteuses, rapides et déterministes, puis ajoutent des vérifications de performances, de sécurité, de résilience et de données à mesure que le pipeline mûrit. Le tableau donne des exemples typiques ; les outils changent, les modèles restent.
Exemples par qualité
| Qualité | Fonction d’aptitude (fitness function) | Type | Outils typiques |
|---|---|---|---|
| Structure | Règles de couches et de dépendances, absence de cycles, modules qui ne s’utilisent entre eux que par des API publiques (section 3.4) | Atomique, déclenchée, statique | ArchUnit, import-linter, dependency-cruiser, vérification Spring Modulith |
| Performances | Test de charge de bout en bout avec seuils de percentiles ; budgets de latence par service dans le pipeline propre à chaque service | Holistique, déclenchée | k6, Gatling, JMeter, Locust ; seuils qui font échouer le job |
| Sécurité | Faire échouer le build sur les dépendances présentant des vulnérabilités connues de gravité élevée ou critique ; aucun secret dans le code ; images de conteneur provenant uniquement du registre approuvé | Atomique, déclenchée | pip-audit, npm audit, OWASP Dependency-Check, Trivy, détecteurs de secrets ; politique en tant que code (section 11.4) |
| Résilience | Expériences de chaos qui arrêtent des instances ou ralentissent des dépendances et vérifient que l’état stable se maintient (section 9.8) | Holistique, déclenchée ou continue | Toxiproxy, Chaos Toolkit, services d’injection de pannes des fournisseurs de cloud |
| Données | Vérifications de compatibilité des schémas sur les événements et les API ; migrations répétées sur des données de la taille de la production (section 7.7) | Atomique, déclenchée | Vérifications de compatibilité du registre de schémas, buf breaking, tests de contrat pilotés par le consommateur |
| Exploitabilité et coût | Chaque service expose des contrôles de santé et des métriques standard ; le coût par commande reste sous une cible | Atomique ou continue | Vérifications du pipeline sur les modèles de service ; tableaux de bord de coûts avec alertes |
Architecture évolutive et changement incrémental
Les fonctions d’aptitude sont l’une des deux moitiés de ce que Ford, Parsons, Kua et Sadalage appellent l’architecture évolutive : une architecture qui permet un changement guidé et incrémental selon de multiples dimensions. Chaque partie de cette formule est une exigence de conception.
Le changement incrémental a un versant développement et un versant exploitation. Les développeurs doivent pouvoir effectuer de petits changements en toute sécurité, ce qui dépend de la modularité et d’un couplage approprié (chapitre 3), ainsi que du fait que chaque partie déployable indépendamment, le quantum d’architecture de la section 5.1, reste assez petite pour être modifiée sans coordination avec les autres. L’exploitation doit pouvoir mettre en production de petits changements fréquemment et en toute sécurité, ce qui dépend d’un pipeline de déploiement, d’un déploiement progressif et d’un retour arrière rapide (section 10.5). Guidé : c’est là qu’interviennent les fonctions d’aptitude ; elles définissent ce que signifie « apte » et empêchent les incréments de le dégrader. Selon de multiples dimensions rappelle que l’architecture n’est pas seulement la structure du code : les données, la sécurité, l’exploitation, la structure des équipes et le coût évoluent tous et ont tous besoin d’être protégés.
Cette approche change la façon dont les architectes pensent l’avenir. Au lieu de prédire chaque exigence et de prévoir à l’avance la flexibilité correspondante, ce qui, comme l’a montré la section 3.8, est coûteux et souvent erroné, l’équipe garde le système facile à modifier et ne protège que les caractéristiques qui comptent, en reportant les autres décisions au dernier moment responsable (section 1.6). Les critiques soulignent de vraies limites. Toutes les qualités ne peuvent pas être vérifiées automatiquement ou à peu de frais ; des seuils mal choisis créent un bruit que les équipes apprennent à ignorer ; et certaines décisions, comme une base de données ou un fournisseur de cloud, restent des portes à sens unique, aussi bon que soit le pipeline. L’architecture évolutive est une discipline qui consiste à garder réversibles les parties réversibles et protégées les parties importantes, et non la promesse que tout pourra être changé plus tard.
Exemple commenté
Exemple commenté : trois scénarios du chapitre 2 transformés en fonctions d’aptitude
La section 2.8 a construit un arbre d’utilité pour la plateforme de livraison de repas. Après que l’ATAM de la section 11.1 a conduit à une autorisation de paiement asynchrone, l’équipe transforme trois de ses feuilles en fonctions d’aptitude : l’une déclenchée et holistique, l’une sous forme d’expérience de chaos, l’une structurelle.
| Scénario 1 : latence des commandes (H,H) | Au pic du vendredi, à 100 commandes/s, 95 % des confirmations de commande reviennent en moins de 1,5 s et 99 % en moins de 3 s |
|---|---|
| Fonction d’aptitude 1 | Holistique, déclenchée : un test de charge k6 sur un environnement semblable à la production, chaque nuit et avant chaque mise en production, qui échoue si le p95 ou le p99 dépasse le seuil ou si plus de 0,1 % des requêtes échouent. Complétée par une supervision continue en production des mêmes percentiles sur le trafic réel |
| Budgets de latence | Les 1,5 s sont répartis en budgets : réseau mobile et TLS 400 ms, passerelle 50 ms, commandes 250 ms, tarification 100 ms, écritures en base de données 150 ms, ce qui laisse 550 ms de marge maintenant que l’autorisation de carte est sortie du chemin. Le pipeline de chaque service exécute un test de charge atomique du composant par rapport à son propre budget, de sorte qu’une régression est détectée dans le service qui l’a causée |
| Scénario 2 : disponibilité du paiement (H,H) | Lorsque le prestataire de paiement dépasse son délai d’expiration pendant le pic, les commandes sont acceptées et mises en file d’attente, aucune commande confirmée n’est perdue, et les clients sont informés en moins de 10 s |
| Fonction d’aptitude 2 | Expérience de chaos holistique, chaque semaine en staging et chaque trimestre sous forme de game day en production avec un faible rayon d’impact : on fait se bloquer le prestataire ; les commandes doivent être acceptées comme en attente en moins de 10 s et toutes doivent être finalisées après le rétablissement. Responsable : équipe Commandes |
| Scénario 3 : nouvel éditeur de caisse (M,L) | Un nouvel éditeur de point de vente (caisse) pour restaurants est intégré en 5 jours-personnes par l’ajout d’un seul adaptateur |
| Fonction d’aptitude 3 | Atomique, déclenchée, statique : un contrat import-linter interdit aux modules de domaine et d’API des restaurants ainsi qu’au paquet des commandes d’importer le SDK d’un éditeur, et un second contrat empêche les adaptateurs de s’importer entre eux, si bien que le changement reste local. Complétée par une vérification manuelle : l’effort de chaque intégration réelle d’éditeur est consigné et comparé à l’objectif de 5 jours |
| Consigné avec chacune | Scénario source, seuil, responsable, ADR qui l’explique et date de revue |
Chaque mesure de la réponse est devenue un seuil sans réinterprétation : c’est le bénéfice d’avoir bien rédigé les scénarios dès le départ.
Le scénario de modifiabilité ne peut pas être entièrement automatisé : la règle structurelle protège les conditions d’un changement en 5 jours, et la mesure manuelle vérifie le résultat.
Les budgets de latence transforment un chiffre holistique unique en vérifications atomiques qui signalent une régression à la bonne équipe.
import http from 'k6/http';
import { check } from 'k6';
export const options = {
scenarios: {
friday_peak: { executor: 'constant-arrival-rate', rate: 100, timeUnit: '1s',
duration: '10m', preAllocatedVUs: 300 }, // 100 orders per second
},
thresholds: { // the scenario's response measure, as pass/fail rules
'http_req_duration{name:place_order}': ['p(95)<1500', 'p(99)<3000'],
'http_req_failed{name:place_order}': ['rate<0.001'],
},
};
const order = { restaurantId: 'r-42', items: [{ sku: 'pad-thai', qty: 1 }] };
export default function () {
const res = http.post(`${__ENV.BASE_URL}/orders`, JSON.stringify(order), {
headers: { 'Content-Type': 'application/json' }, tags: { name: 'place_order' } });
check(res, { 'order accepted': (r) => r.status === 201 || r.status === 202 });
}# Fitness function: checkout keeps accepting orders when payments hang (illustrative)
# Runs weekly in staging; toxiproxy, api and ledger are test fixtures.
def test_orders_survive_payment_provider_outage(toxiproxy, api, ledger):
toxiproxy.add_latency("payment-provider", latency_ms=30_000) # provider hangs
placed = [api.place_order(sample_order()) for _ in range(200)]
assert all(r.status in (201, 202) for r in placed) # still accepted
assert all(r.json()["state"] == "PENDING_PAYMENT" for r in placed)
assert max(r.elapsed_seconds for r in placed) < 10 # told within 10 s
toxiproxy.remove_toxics("payment-provider") # provider recovers
ledger.wait_until_settled(timeout_seconds=300)
assert ledger.lost_orders(placed) == [] # none lost# .importlinter: only the POS adapters may use vendor SDKs
[importlinter]
root_package = fooddelivery
include_external_packages = True
[importlinter:contract:pos-vendors-isolated]
name = Vendor POS SDKs are used only inside the POS adapters
type = forbidden
source_modules =
fooddelivery.restaurant.domain
fooddelivery.restaurant.api
fooddelivery.ordering
forbidden_modules =
tillpro_sdk
kitchenlink
[importlinter:contract:adapters-independent]
name = POS adapters do not import each other
type = independence
modules =
fooddelivery.restaurant.pos_adapters.tillpro
fooddelivery.restaurant.pos_adapters.kitchenlinkLa compatibilité des données est protégée de la même manière. Avant qu’une modification de l’événement OrderPlaced puisse être fusionnée, le pipeline demande au registre de schémas si le nouveau schéma est compatible avec la dernière version enregistrée selon la règle de compatibilité du sujet, et échoue s’il ne l’est pas :
# Data fitness function: block the merge if the new event schema would break consumers
curl -s -X POST -H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data @build/order-placed-v7.request.json \
"$SCHEMA_REGISTRY_URL/compatibility/subjects/order-placed-value/versions/latest" \
| jq -e '.is_compatible == true'Concevoir des fonctions d’aptitude durables
Commencez petit, et par l’important. Choisissez les trois à cinq caractéristiques les mieux classées dans l’arbre d’utilité, écrivez une fonction d’aptitude pour chacune et assurez-vous qu’elles sont rapides et fiables avant d’en ajouter d’autres. Une douzaine de vérifications dignes de confiance valent mieux qu’une centaine qui échouent au hasard.
Appliquez un effet cliquet aux systèmes existants. Quand une base de code enfreint déjà une règle, consignez les violations actuelles comme base de référence et ne faites échouer le build que sur les nouvelles ; resserrez la base de référence à mesure que l’équipe rembourse la dette. Il en va de même pour les performances : faites échouer le build en cas de régression supérieure à une marge convenue par rapport à la dernière version, tout en progressant vers l’objectif du scénario.
Rendez les seuils explicites et attribuez-leur un responsable. Conservez les seuils dans une configuration sous contrôle de version, à côté d’une référence à l’ADR qui les justifie, avec un responsable nommé. Quand une fonction d’aptitude échoue, le responsable choisit entre corriger le code et changer la règle, et la décision est consignée. Traitez une fonction d’aptitude fréquemment contournée comme un constat : soit la règle est mauvaise, soit l’architecture subit une pression réelle.
Gardez le pipeline rapide. Les vérifications atomiques ont leur place dans chaque build ; les vérifications holistiques lourdes, comme les tests de charge de dix minutes, s’exécutent chaque nuit, avant la mise en production ou sur la version candidate. Les vérifications continues en production demandent le même soin que n’importe quelle alerte : liées à l’impact sur les utilisateurs, accompagnées d’un runbook, et silencieuses quand tout va bien.
Questions fréquentes
Les fonctions d’aptitude ne sont-elles que des tests ?
Beaucoup sont mises en œuvre sous forme de tests, mais leur objet est différent. Les tests ordinaires vérifient que les fonctionnalités se comportent correctement ; les fonctions d’aptitude vérifient des caractéristiques d’architecture comme la structure, la latence, la résilience ou la compatibilité. Certaines, comme les sondes de supervision en production et les revues manuelles, ne sont pas du tout des tests.
Qui écrit les fonctions d’aptitude : les architectes ou les développeurs ?
Les deux. Les architectes identifient généralement les caractéristiques et les seuils, et écrivent souvent les premières vérifications, ce qui est un bon moyen de garder les mains dans le code (section 1.4). Les équipes en sont propriétaires et les maintiennent comme n’importe quel autre code.
Quel est le lien entre les fonctions d’aptitude et les SLO ?
Un SLO assorti d’une alerte sur son budget d’erreur est une fonction d’aptitude continue et holistique pour la disponibilité ou la latence en production (section 9.5). Les fonctions d’aptitude du pipeline cherchent à détecter les mêmes régressions avant qu’elles n’atteignent les utilisateurs.
Vérifiez votre compréhension
Quelle est la différence entre une métrique et une fonction d’aptitude ?
Une métrique décrit une propriété ; une fonction d’aptitude encode une décision avec un seuil et une action, si bien que l’enfreindre fait échouer un build ou déclenche une alerte et impose un choix conscient.
Donnez un exemple de fonction d’aptitude atomique et un exemple de fonction d’aptitude holistique.
Atomique : une règle qui interdit les imports de la couche web dans le domaine. Holistique : un test de charge qui mesure la latence des commandes avec la sécurité, la journalisation et le cache tous actifs.
Qu’apporte un budget de latence à une fonction d’aptitude de latence de bout en bout ?
Il répartit l’objectif de bout en bout en limites par service, que chaque service vérifie dans son propre pipeline, de sorte qu’une régression est détectée dans le service qui l’a causée.
Quelles sont les trois parties de la définition de l’architecture évolutive ?
Elle permet un changement guidé (par les fonctions d’aptitude), incrémental (petits changements et mises en production sûrs) et selon de multiples dimensions (code, données, sécurité, exploitation, équipes, etc.).
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 : « Quelles trois fonctions d’aptitude devrions-nous écrire en premier pour un service qui doit confirmer les commandes rapidement et survivre à une panne du prestataire de paiement ? »