Guide complet gratuit

messagerie instantanée

Concevez messagerie instantanée.

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

01Juste du tête-à-tête, ou des groupes aussi — et jusqu'à quelle taille un groupe peut-il aller ?

Les utilisateurs envoient et reçoivent des messages en 1:1 et en groupe. Les groupes sont plafonnés autour de 100 participants, ce qui garde le fan-out par message borné.

02Qu'advient-il des messages envoyés pendant que je suis hors ligne ?

Les messages envoyés hors ligne sont livrés à la reconnexion de l'appareil. Ils sont gardés jusqu'à 30 jours. Le serveur est un relais avec un tampon limité, pas une archive permanente.

03Un seul téléphone par utilisateur, ou chaque appareil synchronisé ?

Les utilisateurs peuvent joindre des médias, et chaque appareil qu'un utilisateur possède reste synchronisé — chaque appareil suit son propre état de livraison.

04Accusés de lecture et indicateurs de saisie — dans le périmètre ?

Les accusés de réception oui : ils empruntent le même chemin de livraison par appareil que les messages. Les indicateurs de saisie sont temporaires. Ils sont au mieux, et jamais stockés.

05Un utilisateur peut-il supprimer un message envoyé pour tout le monde ?

La suppression pour tous est un événement tombstone qui voyage exactement comme un message normal. Les clients qui ont déjà affiché le message le remplacent sur place. Les modifications restent hors périmètre.

06Quelqu'un rejoint ou quitte un groupe en pleine conversation — que voit-il ?

Rejoindre ou quitter un groupe est un événement ordonné dans la conversation. Ceux qui rejoignent reçoivent les messages à partir du point de jonction. Ceux qui partent cessent de recevoir à l'événement de départ. Personne ne reçoit un historique partiel.

Hors périmètreLes appels audio et vidéo · La messagerie professionnelle et les chatbots · L'inscription et la gestion de profil

Besoins non fonctionnels

01À quelle vitesse un message doit-il atteindre quelqu'un en ligne ?

Moins de 500 ms de bout en bout — un chat semble instantané, sinon il semble cassé.

02Un message peut-il jamais disparaître en silence ?

Non. La livraison est garantie. Le message est écrit durablement avant toute tentative de livraison, si bien qu'une connexion coupée le retarde mais ne le perd jamais.

03Pour quelle échelle concevons-nous ?

200M d’actifs quotidiens envoyant ~20 messages par jour, environ la moitié en ligne à tout instant.

04Combien de temps les serveurs gardent-ils le contenu des messages ?

Pas plus longtemps que nécessaire : un TTL (time-to-live) de 30 jours sur la boîte de réception non livrée, puis disparu.

05Que se passe-t-il quand un serveur de chat tombe ?

Ses utilisateurs se reconnectent à un autre serveur et se synchronisent depuis l'inbox. L'état de livraison vit dans le stockage, pas dans la mémoire du serveur, donc aucun message n'est perdu.

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.

  • Plafond de taille de groupe — des centaines ou des milliers ? Le design du fan-out en dépend.
  • L'ack que voit l'expéditeur est-il « livré au serveur » ou « livré à l'appareil » ?
  • Combien d'appareils par compte doivent rester synchronisés ?
  • L'historique des messages est-il une archive permanente, ou un tampon relais de 30 jours ?
  • Le chiffrement de bout en bout est-il dans le périmètre ? Il change ce que le serveur peut stocker.
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

Débit d'écriture de messages

200M utilisateurs actifs × ~20 messages/jour200M × 20 = 4B messages/jour ; 4B ÷ 86 400 s ≈ 46K msg/s envoyés ; fan-out de groupe ×2-3 ≈ 100K écritures/s

Message et Inbox ont besoin d'un stockage optimisé pour l'écriture (LSM log-structured merge trees / wide-column). Le travail de fan-out croît avec le nombre de participants, ce qui explique pourquoi les groupes sont plafonnés.

02

Connexions simultanées

200M d’actifs quotidiens, environ la moitié en ligne à tout instant200M × ~50 % ≈ 100M de connexions WebSocket ouvertes

Avec des sockets persistants, c'est le nombre de connexions qui dimensionne la flotte de gateways, pas le débit de requêtes.

03

Connexions par gateway

~1M connexions WebSocket concurrentes par gros serveur gateway100M en ligne simultanément ÷ 1M ≈ 100+ gateways

Les utilisateurs sont hachés vers les gateways (consistent hashing + registry) pour que le routage de message trouve le bon serveur.

04

Taille de la boîte de réception hors ligne

TTL de 30 jours, ~1KB par référence de messagemême 1,000 messages non livrés ≈ 1 MB par utilisateur dormant

Le TTL garde le filet de secours petit. Les appareils longtemps dormants resynchronisent plutôt leur historique depuis le store Message.

Exemple de décision

Les chiffres

Cent mille écritures par seconde, cent millions de personnes en ligne à la fois, et une promesse : moins d'une demi-seconde, et jamais rien perdu en silence.

Mon choix

Garder les gateways sans état — ils ne font que tenir les sockets et relayer. Chaque message est écrit dans le store Message et dans l'Inbox de chaque destinataire avant tout push, si bien que rien ne vit qu'en mémoire. La livraison inter-serveurs emprunte un pub/sub partitionné par ID utilisateur, si bien que chaque gateway ne s'abonne qu'à ses propres utilisateurs. L'ordre est l'heure de réception au serveur ; en chat, rapide vaut mieux que parfaitement ordonné.

À éviter

Ce que je NE ferais PAS : garder les messages non livrés dans la mémoire de la gateway. Un crash et ils sont perdus, ce qui casse la promesse fondamentale. Je ne partitionnerais pas non plus le pub/sub par ID de conversation. Un groupe animé deviendrait une partition chaude, donc partitionnez par utilisateur à la place. Et je n'ajouterais pas de couches de sharding avant d'avoir mesuré le vrai débit de messages par partition. Sharder trop tôt ajoute des modes de défaillance, pas de la capacité.

Changer si

Si le chiffrement de bout en bout entre dans le périmètre, le serveur ne peut être qu'un routeur aveugle de texte chiffré. L'Inbox et la synchronisation multi-appareils passent alors à des copies de message par appareil et à des clés détenues par le client.

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

Client(WebSocket)ConnectionGatewayMessage ServiceMessage + InboxStoreRecipientGatewaysPub/Sub (peruser)router vers les gatewaysConnectionRegistrycorrespondance user → gatewayPushNotificationappareils hors ligne

Écriture durable d'abord, livraison ensuite. Les gateways sont des porteurs de sockets sans état. Le registre sait qui est connecté où, et les appareils hors ligne reçoivent un push au lieu d'une trame socket.

Chemin 1

Chemin d'envoi — durable d'abord, puis fan-out

Sender ClientGatewayMessage ServiceMessage + InboxStorePub/Sub →Gateways

L'accusé de l'expéditeur part après l'écriture durable. Le pub/sub atteint ensuite chaque gateway tenant un appareil destinataire. Un publish manqué est sans danger — l'inbox l'a déjà.

Chemin 2

Chemin de reconnexion — vider la boîte de réception

Client(reconnect)GatewayInbox(undelivered)Message StoreClient synced

À la reconnexion, le client draine son inbox et compare les numéros de séquence. Tout ce qui a été manqué en transit est tiré, puis la livraison en temps réel reprend.

04

API et modèle de données

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

WSsendMessage { chat_id, body, attachments[] }

rés{ message_id, status } — ack after durable write

L'ack signifie « stocké », pas « livré » — la durabilité d'abord, la livraison ensuite.

WSnewMessage → client { chat_id, sender, body }

résclient replies RECEIVED

Poussé sur la connexion persistante vers chaque appareil en ligne de chaque participant.

POST/attachments

req{ body: presigned upload }

rés200 { attachment_id, url }

Les médias vont vers le stockage blob via une URL présignée ; les messages ne portent que la référence opaque.

WSheartbeat every 10-30 s (piggybacks last sequence)

résclient compares and syncs gaps

Les heartbeats détectent les connexions mortes ET servent aussi de canal de détection de trous.

Entités principales

Chat

chat_id (PK) · participants (≤100) · name

Message

message_id (PK) · chat_id · sender_id · body · attachments · server_ts

Ordonné et affiché selon l'horodatage de réception serveur — les utilisateurs préfèrent voir les messages vite plutôt que dans un ordre d'envoi parfait.

Inbox

user_id (PK) · message_id · ttl_30d

Le filet de sécurité de durabilité : écrit AVANT toute tentative de push, vidé à la reconnexion.

Client

user_id (PK) · client_id · last_seen

Un utilisateur, plusieurs appareils (plafond ~3) — la livraison est suivie par client, pas par utilisateur.

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

Cent millions de sockets ouvertes

Question

Comment des centaines de millions d'utilisateurs tiennent-ils des connexions persistantes, et comment un message trouve-t-il l'unique gateway tenant son destinataire ?

Réponse

Chaque gateway tient ~1M de sockets ; un registre mappe user → gateway, et le pub/sub partitionné par user ID ne livre chaque message qu’au gateway qui tient son destinataire.

À éviter

Diffuser chaque message à chaque gateway — n'abonnez les gateways qu'à leurs propres utilisateurs connectés.

Focus

Le destinataire est hors ligne

Question

Où le message attend-il, combien de temps, et que se passe-t-il au moment où il se reconnecte ?

Réponse

Il attend dans l’inbox durable du destinataire (TTL 30 jours) ; à la reconnexion le client draine le retard, et le service de notifications push réveille les appareils inactifs entre-temps.

À éviter

Compter sur le pub/sub pour la durabilité — il est at-most-once ; l'écriture dans la boîte de réception doit venir d'abord.

Focus

Deux téléphones, un compte

Question

Un utilisateur lit un message sur son ordinateur portable. Que doit savoir son téléphone, et comment l'état par appareil est-il suivi ?

Réponse

L’état de livraison et de lecture est suivi par appareil, pas par utilisateur ; chaque appareil se synchronise depuis son propre curseur, le téléphone tire exactement ce qu’il n’a pas encore vu.

À éviter

Suivre la livraison par utilisateur plutôt que par client — le second appareil rate silencieusement des messages.

Focus

Les messages arrivent dans le désordre

Question

Deux messages font la course à travers des gateways différents. Dans quel ordre le destinataire les voit-il, et pourquoi est-ce acceptable ?

Réponse

L’ordre est l’heure de réception serveur par conversation, et les clients affichent selon ce timestamp ; une brève course entre gateways est invisible en pratique, alors que bloquer pour un ordre global coûte une latence que les utilisateurs remarquent.

À éviter

Bloquer la livraison pour imposer un ordre global — les utilisateurs préfèrent rapide à parfaitement séquencé.

Focus

Un gateway meurt en pleine conversation

Question

Dix mille utilisateurs tombent d'un coup. Que perdent-ils, et à quelle vitesse redeviennent-ils entiers ?

Réponse

Rien n’est perdu — les messages non livrés vivent dans des inbox durables, pas en mémoire de gateway. Les clients se reconnectent ailleurs, et le heartbeat de 10-30 s portant le dernier numéro de séquence permet à chaque client de repérer son trou et de le combler.

À éviter

Tout design où la mémoire du gateway est l'unique copie d'un message non livré.

Prêt à vous entraîner ?

Expliquez messagerie instantanée à voix haute et obtenez une évaluation IA de votre explication.

S’entraîner avec l’IA →