00

Points de contrôle de pratique

Le rythme de l’entretien reste compact, pour que la page consacre son attention aux vraies décisions de conception.

  1. 01
    Clarifier le périmètre
  2. 02
    Besoins + échelle
  3. 03
    API + modèle de données
  4. 04
    Dessiner l’architecture
  5. 05
    Deep dive
  6. 06
    Décision de compromis
01

Les besoins qui façonnent la conception

Ne vous contentez pas d’énoncer les besoins : demandez-les. Chaque carte associe la contrainte de conception à une question de clarification que vous pouvez dire à voix haute avant de dessiner l’architecture.

Besoins fonctionnels

01Que doivent faire les utilisateurs — parcourir et rechercher des événements, ou est-ce uniquement de la réservation ?

Les utilisateurs peuvent consulter un événement avec le plan de salle de son lieu et une disponibilité en quasi-temps réel, et rechercher des événements par mot-clé, date et lieu.

02Quand un utilisateur choisit des sièges, obtient-il un blocage temporaire pendant qu'il paie ?

Les utilisateurs peuvent choisir des sièges et obtenir une réservation de courte durée (5-10 minutes). Ils réservent d'abord, puis confirment avec le paiement. Une réservation jamais confirmée se libère automatiquement.

03Quelle est la seule garantie que nous ne pouvons jamais rompre ?

Une réservation est définitive : chaque siège se vend exactement une fois — jamais de double réservation, même pendant une mise en vente flash.

04Sélection sur plan de salle, attribution best-available, ou les deux ?

Les deux. Sélection sur plan pour les salles à sièges réservés, plus le meilleur disponible. Même le meilleur disponible prend des réservations atomiques sur des sièges précis, jamais un vague décompte.

05Un acheteur peut-il ajouter des sièges à un blocage existant en cours de paiement ?

Oui, tant que la réservation est encore vivante. Les sièges ajoutés prennent leurs propres réservations, jointes atomiquement à la même commande. Ils confirment tous ensemble, ou l'ajout échoue proprement.

06Complet — avons-nous besoin d'une liste d'attente ?

Hors périmètre au jour un — mais une liste d'attente est une suite probable, donc les choix du jour un ne devraient pas rendre pénible l'ajout de l'une d'elles.

Hors périmètreTarification dynamique pour les événements très demandés · Outils d'administration et de coordination d'événements pour créer des événements · Consultation des réservations passées, transfert de billets et revente

Besoins non fonctionnels

01Où avons-nous besoin d'une cohérence forte, et où les données peuvent-elles être périmées ?

La réservation a besoin d'une cohérence forte, pour qu'un siège ne soit jamais vendu deux fois. La navigation et la recherche n'ont besoin que de la disponibilité. Le plan de salle peut retarder de quelques secondes sur la réalité.

02À quoi ressemble une mise en vente flash au pic ?

Un seul événement chaud peut attirer ~10M d'utilisateurs au moment de la mise en vente. Le système doit absorber ce pic. Il vaut mieux faire attendre les utilisateurs équitablement que les faire échouer.

03À quelle vitesse la navigation et la recherche doivent-elles paraître ?

Recherche sous ~500 ms ; les vues du plan de salle doivent sembler instantanées même pendant une ruée. À forte dominante de lecture, environ 100:1.

04Combien de temps un blocage peut-il durer, et que se passe-t-il à son expiration ?

Les réservations sont courtes (5-10 minutes) avec libération automatique par TTL. Les paniers abandonnés rendent les sièges sans nettoyage manuel. Les réservations doivent aussi survivre à la latence du prestataire de paiement.

05Si une confirmation arrive deux fois — un double clic, ou le prestataire de paiement qui retente un webhook — le débit et la vente doivent-ils quand même n'avoir lieu qu'une seule fois ?

Les nouvelles tentatives et les webhooks de paiement dupliqués ne doivent jamais débiter deux fois ni réserver deux fois — confirmer deux fois doit avoir le même effet que confirmer une fois.

Continuez à demander — l’entretien est une conversation

Les vrais entretiens sondent bien plus qu’une liste propre. Ces questions de périmètre séparent ceux qui interrogent le problème de ceux qui le récitent.

  • Places numérotées avec un plan de salle, ou admission générale avec un compteur de capacité — ou les deux ?
  • Les remboursements ou annulations remettent-ils les sièges en vente, ou est-ce hors périmètre ?
  • Y a-t-il une limite de billets par utilisateur et par événement que nous devons appliquer ?
  • Gérons-nous nous-mêmes les détails de carte, ou déléguons-nous à un prestataire de paiement — la conformité PCI nous incombe-t-elle ?
  • L'atténuation des bots et des revendeurs est-elle dans le périmètre ?
02

Les chiffres qui forcent les décisions d’architecture

Traitez chaque estimation comme une pression qui justifie un composant : cache, file, partition, réplica, pool de workers ou chemin de repli.

01

Contention à la mise en vente

~10M d'utilisateurs (issus de l'exigence de mise en vente) se disputent ~50K sièges supposés à un instant de mise en vente10,000,000 ÷ 50,000 ≈ 200 utilisateurs par siège

Presque tout le monde doit patienter dans la salle d'attente — le contrôle d'admission décide qui parvient ne serait-ce qu'à la réservation.

02

Rafale d'écritures de réservation

Première minute de la mise en vente : chaque utilisateur admis tente un blocageadmettre 50K utilisateurs/min ≈ 800 tentatives de réservation/s sur une partition d'événement

Le partitionnement par événement et des transitions atomiques courtes gardent la partition chaude en vie. Les autres événements restent intacts.

03

Asymétrie des lectures de navigation

Dominé par la lecture à ~100:1 — le sondage du plan de salle domine800 écritures/s × 100 ≈ 80K lectures du plan de salle/s au pic

Servir les vues depuis le cache/CDN avec quelques secondes de péremption — la base d'inventaire ne voit jamais le trafic de navigation.

04

TTL du blocage vs latence de paiement

Le p95 de la confirmation de paiement externe est en secondes ; les utilisateurs remplissent des formulaires pendant des minutesTTL 5-10 min ≫ p95 paiement ~3-10 s

Un TTL généreux évite que les blocages expirent en plein paiement ; l'expiration libère automatiquement les sièges abandonnés sans tâches de nettoyage.

05

Budget de latence de recherche

Cible de recherche < 500 ms de bout en boutrequête index inversé ~50-100 ms + classement + réseau ≈ bien en dessous de 500 ms

Un index plein texte (pas de balayages LIKE) est requis ; mettre en cache les requêtes répétées et servir via CDN les résultats non personnalisés.

Exemple de décision

Les chiffres

Imaginez la mise en vente : ~10M de personnes veulent ~50K sièges — environ 200 personnes par siège. La bataille porte sur l'état de chaque siège, donc les écritures sur un siège doivent se faire une à la fois. Pendant ce temps, tous ceux qui ne font que naviguer sont servis depuis le cache.

Mon choix

Je ferais trois choses. Premièrement, mettre tout le monde dans une salle d'attente et les laisser entrer dans le flux de réservation à un rythme contrôlé, pour que la base des sièges ne voie jamais qu'un trafic qu'elle peut supporter. Deuxièmement, quand un utilisateur choisit des sièges, les bloquer 5-10 minutes — payer dans cette fenêtre ou les sièges reviennent automatiquement en vente. Troisièmement, faire de « vérifier que le siège est libre ET le marquer bloqué » une seule étape atomique (un verrou de ligne, ou une mise à jour qui ne réussit que si personne n'a modifié le siège entre-temps), pour que deux acheteurs ne puissent jamais l'attraper tous les deux.

À éviter

Ce que je ne ferais PAS : lire « le siège est libre » d'abord, puis le marquer bloqué dans une seconde étape. Dans l'intervalle entre ces deux étapes, un autre acheteur peut faire la même lecture — les deux croient avoir gagné, et le siège se vend deux fois. La vérification et la mise à jour doivent être une seule étape, et le perdant doit recevoir une réponse claire « quelqu'un vous a devancé » (HTTP 409), pas un échec silencieux.

Changer si

Si la salle est en placement libre, sans sièges précis et juste un nombre de places, le verrouillage par siège est excessif. Je garderais un seul compteur atomique de capacité restante et j'arrêterais la vente quand il atteint zéro.

03

Chemin d’architecture

D’abord une image complète, puis chaque chemin comme son propre schéma — le chemin d’écriture et le chemin de lecture portent un trafic différent et justifient des composants différents.

Image complète

Vue d’ensemble — chaque composant

ClientAdmissionControlBooking ServiceHold Store (TTL)Seat InventoryDBPayment Serviceconfirmation idempotenteSeat-Map Cache +Searchlectures navigation / recherche

La réservation est la colonne vertébrale ; la navigation et la recherche ne touchent jamais l'inventaire des sièges (pointillés = côté lecture, hors du chemin critique de réservation). Un blocage expiré rend les sièges automatiquement.

Chemin 1

Chemin de réservation — réserver, puis confirmer

ClientAdmissionControlBooking ServiceHold Store (TTL)Seat InventoryDBPayment Service
  • Réserver pose un blocage avec un compte à rebours (TTL) — si l'acheteur ne paie jamais, le blocage expire et le siège revient en vente de lui-même.
  • Confirmer débite le paiement et bascule les sièges bloqués en vendus en une seule étape atomique ; retenter la confirmation ne débite ni ne réserve jamais deux fois.
  • « Ce siège est-il libre ? » et « le marquer bloqué » doivent être une seule et même étape — un verrou de ligne, ou une mise à jour qui ne réussit que si le siège n'a pas changé entre-temps (compare-and-set).
  • Si c'étaient deux étapes distinctes, deux acheteurs pourraient tous deux passer la vérification dans l'écart entre elles — et le siège se vendrait deux fois.

Chemin 2

Chemin de navigation — recherche et plan de salle (dominé par la lecture)

ClientCDN / EdgeEvent + SearchServiceSeat-Map CacheDatabase

Les pages d'événement sont pré-rendues et mises en cache CDN, si bien qu'une vente flash ne touche jamais les serveurs applicatifs pour le contenu statique. La disponibilité peut retarder de quelques secondes. La transaction de réservation est là où la vérité est imposée.

04

API et modèle de données

Avant d’optimiser, rendez le contrat inspectable : endpoints, entités, propriété, retries et état.

GET/events/{event_id}

rés200 { event, venue, seat_map, availability }

Cache/CDN d'abord ; la disponibilité peut accuser quelques secondes de retard — c'est à la réservation que la vérité est imposée.

GET/events/search?keyword&date&location

rés200 Event[]

Index inversé (plein texte) — moins de 500 ms, correspondances approximatives comprises.

POST/bookings

req{ event_id, ticket_ids[] }

rés201 { booking_id, hold_expires_at } · 409 siège déjà bloqué ou vendu

Crée le blocage TTL : les sièges passent à held de façon atomique ou toute la requête échoue — pas de blocages partiels.

POST/bookings/{booking_id}/confirm

req{ payment_token, idempotency_key }

rés200 confirmé · 402 paiement échoué (le blocage continue de courir) · 410 blocage expiré

Idempotent par booking_id : les nouvelles tentatives du prestataire de paiement et les webhooks en double sont sans danger.

Entités principales

Event

event_id (PK) · venue_id · performer · starts_at · on_sale_at

Ticket

ticket_id (PK) · event_id · section/row/seat · price · status: available/held/booked · version

status + version pilotent la concurrence optimiste ; partitionner par event_id pour qu'une mise en vente ne dégrade pas les autres événements.

Booking

booking_id (PK) · user_id · ticket_ids · total · status: pending/confirmed/failed · idempotency_key

User

user_id (PK) · email · created_at

05

Directions de deep dive

Choisissez une voie pour le dernier tiers de l’entretien. Chaque voie vous donne le sujet, la question de l’examinateur à laquelle répondre, et le mode d’échec à éviter.

Focus

États du siège

Question

Faites passer un siège par available → held → sold. Qu'est-ce qui fait basculer chaque état exactement, et deux personnes peuvent-elles jamais bloquer le même siège ?

Réponse

Une seule écriture atomique fait passer un siège de disponible à réservé. Elle ne réussit que si le siège est encore disponible, donc un deuxième acheteur échoue tout simplement. Deux personnes ne peuvent pas réserver le même siège, parce que la vérification et le basculement ne font qu'une étape. La confirmation transforme réservé en vendu après paiement ; un TTL expiré le renvoie à disponible.

À éviter

Des blocages sans TTL — les paniers abandonnés verrouillent les sièges pour toujours.

Focus

Réserver d'abord, confirmer ensuite

Question

Pourquoi bloquer le siège avant le paiement, et que lui arrive-t-il si le paiement n'aboutit jamais ?

Réponse

Réservez le siège d'abord pour qu'il reste à l'acheteur pendant qu'il saisit ses détails de carte. Si vous le marquiez vendu au moment de la réservation, chaque paiement échoué ou abandonné bloquerait un siège invendable. Quand le paiement n'aboutit jamais, le TTL fait expirer la réservation et le siège se remet en vente automatiquement — aucune tâche de nettoyage nécessaire.

À éviter

Marquer le siège vendu au moment de la réservation — un paiement échoué le rend alors invendable.

Focus

Empêcher la double vente

Question

Verrou de ligne, vérification de version (CAS) ou compteur atomique — comment chacun empêche deux acheteurs de gagner le même siège, et que coûte chacun sous contention ?

Réponse

Pour les sièges réservés, utilisez de courts verrous de ligne ou des mises à jour conditionnelles en une seule instruction, et plafonnez la contention avec le contrôle d'admission. Un verrou de ligne sérialise les acheteurs : toujours correct, mais ils font la queue sur les lignes chaudes. Une vérification de version (CAS) évite les verrous, mais à ~200 acheteurs par siège la plupart réessaient et perdent encore. Un compteur atomique ne convient qu'aux sièges interchangeables — l'admission générale.

À éviter

Des tentatives purement optimistes lors d'une vente flash — la plupart des acheteurs échouent encore et encore au lieu d'attendre équitablement.

Focus

Survivre au pic de mise en vente

Question

10M de personnes frappent une mise en vente. Comment les faire attendre équitablement au lieu d'en rejeter la plupart par des erreurs ?

Réponse

Mettez les 10 M dans une salle d'attente et admettez-les à un rythme contrôlé. Un token bucket libère environ 50 K utilisateurs par minute dans le flux de réservation, si bien que l'inventaire de sièges ne voit jamais que du trafic qu'il peut encaisser. Tous les autres gardent une position de file équitable au lieu de marteler « réessayer » contre des erreurs. Les autres événements ne sentent jamais le pic.

À éviter

Laisser toute la foule atteindre l'inventaire des sièges — la salle d'attente existe pour le protéger.

Focus

Payer exactement une fois

Question

La requête de confirmation arrive deux fois — une nouvelle tentative ou un double clic. Comment garantir que la carte est débitée une fois et le siège vendu une fois ?

Réponse

La confirmation porte une clé d'idempotence, le booking_id, et le service stocke le résultat de la première tentative. Toute nouvelle tentative ou webhook dupliqué avec la même clé récupère ce résultat stocké au lieu de s'exécuter à nouveau. Donc quel que soit le nombre de fois où la requête arrive, la carte est débitée une fois et le siège vendu une fois.

À éviter

Pas de clé d'idempotence sur la confirmation — une nouvelle tentative réseau double la facturation ou la vente.

Prêt à vous entraîner ?

Expliquez système de billetterie à voix haute et obtenez une évaluation IA de votre explication.

S’entraîner avec l’IA →