MFormations
Modern Backend Engineering

Chapitre 1

Chapitre 01 — Fondamentaux Backend

Chapitre 01 — Fondamentaux Backend

Cours complet — Fondamentaux Backend

1. HTTP/1.1, HTTP/2, HTTP/3

HTTP/1.1 (RFC 2616, 1999)

  • Connexion : TCP par requête ou keep-alive (Connection: keep-alive)
  • Pipeline : théoriquement possible, rarement implémenté (HOL blocking)
  • Head-of-Line blocking : une requête lente bloque les suivantes sur la même connexion
  • Compression : gzip, deflate sur le body (pas les headers)
  • Methodes : GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE, CONNECT
  • Status codes : 1xx (info), 2xx (success), 3xx (redirect), 4xx (client error), 5xx (server error)

Problèmes HTTP/1.1 :

  • Multiplexage impossible (1 requête = 1 connexion TCP)
  • Headers non compressés (répétés, verbeux)
  • Priority non gérée
  • Server push inexistant

HTTP/2 (RFC 7540, 2015)

  • Binaire (pas textuel) : frames + streams
  • Multiplexage : plusieurs requêtes simultanées sur une connexion TCP
  • HPACK : compression des headers (Huffman + table)
  • Server push : serveur envoie des ressources avant demande
  • Stream priority : arbre de priorisation
  • Flow control : contrôle de flux par stream
┌─────────────────────────────────────────┐
│         Connexion TCP unique            │
├────────┬────────┬────────┬──────────────┤
│Stream1 │Stream2 │Stream3 │ ...          │
│Req 1   │Req 2   │Req 3   │              │
│Frame 1 │Frame 1 │Frame 1 │              │
│Frame 2 │Frame 2 │...     │              │
│...     │...     │        │              │
└────────┴────────┴────────┴──────────────┘

HOL blocking persiste : un paquet TCP perdu bloque tous les streams (car un seul TCP).

HTTP/3 (RFC 9114, 2022)

  • QUIC (transport UDP) au lieu de TCP
  • 0-RTT : reprise de session sans handshake
  • Connection migration : changement d'IP sans reconnexion (mobile)
  • No HOL blocking : perte d'un paquet n'affecte que le stream concerné
  • QPACK : compression headers adaptée à QUIC
  • Built-in TLS 1.3 : chiffrement natif

QUIC vs TCP :

FeatureTCPQUIC
TransportTCP (kernel)UDP (userspace)
Handshake3-way + TLS = 2-3 RTT0-1 RTT
HOL blockingOui (TCP)Non (par stream)
MigrationNonOui
User-spaceNonOui (implémentations ex: quinn, s2n-quic)

HTTP Methods (idempotence)

MethodIdempotentSafePayload
GETOuiOuiNon
HEADOuiOuiNon
POSTNonNonOui
PUTOuiNonOui
DELETEOuiNonNon*
PATCHNon*NonOui
OPTIONSOuiOuiNon

2. TCP/IP, UDP, Sockets

TCP (Transmission Control Protocol)

  • Orienté connexion : 3-way handshake (SYN, SYN-ACK, ACK)
  • Fiable : accusés de réception, retransmission
  • Ordonné : séquencement des paquets
  • Flow control : sliding window (récepteur contrôle débit)
  • Congestion control : slow start, congestion avoidance, fast retransmit (algo: Reno, Cubic, BBR)
  • Headers : 20-60 bytes (source/dest port, seq/ack num, flags, window size, checksum)

3-way handshake :

Client → SYN (seq=x)               → Serveur
Client ← SYN-ACK (seq=y, ack=x+1)  ← Serveur
Client → ACK (seq=x+1, ack=y+1)    → Serveur

TCP Flags : SYN, ACK, FIN, RST, PSH, URG

UDP (User Datagram Protocol)

  • Sans connexion : pas de handshake
  • Non fiable : pas de garantie de livraison
  • Non ordonné : pas de séquencement
  • Léger : 8 bytes de header
  • Usages : DNS, DHCP, streaming, VoIP, QUIC, gaming

TCP vs UDP

CritèreTCPUDP
FiabilitéGarantieAucune
OrdreGarantiNon
VitessePlus lentPlus rapide
OverheadÉlevé (20-60 bytes)Faible (8 bytes)
Cas d'usageHTTP, SMTP, SSH, FTPDNS, VoIP, gaming, QUIC

Sockets

  • socket() : création (domain, type, protocol)
  • bind() : attache à une adresse/port
  • listen() : écoute (TCP serveur)
  • connect() : connexion (TCP client)
  • accept() : accepte connexion (TCP serveur)
  • send()/recv() : envoi/réception
  • close() : fermeture

Socket types :

  • SOCK_STREAM : TCP (fiable, ordonné)
  • SOCK_DGRAM : UDP (non fiable)
  • SOCK_RAW : accès direct IP

Non-blocking I/O :

// set non-blocking
fcntl(sock, F_SETFL, O_NONBLOCK);
// ou utiliserr select()/poll()/epoll()/kqueue

epoll (Linux) / kqueue (BSD/macOS) / IOCP (Windows)

  • select() : O(n), limite FD_SETSIZE (1024)
  • poll() : O(n), pas de limite fixe
  • epoll() : O(1), edge/level-triggered, scalable (millions de sockets)
  • kqueue : O(1), BSD/macOS, filtres variés
  • IOCP : Windows, completion ports

3. Processus, Threads, Async

Processus

  • Espace mémoire isolé : heap, stack, code, data segments
  • Communication : pipes, sockets, shared memory, message queues
  • Création : fork() (Unix), CreateProcess() (Windows)
  • État : running, ready, blocked, terminated
  • Context switch : lourd (changement d'espace d'adressage)

Threads

  • Même espace mémoire (heap partagé, stack privé)
  • Création : pthread_create(), std::thread
  • Context switch : léger (même espace d'adressage)
  • Problèmes : race conditions, deadlocks, data races
  • Synchronisation : mutex, semaphore, condition variable, barrier

Race condition :

// Thread 1 et 2 incrémentent x en même temps
// Problème : read-modify-write non atomique
// Solution : mutex ou std::atomic<int>

Deadlock :

Thread A: lock(m1) → lock(m2)
Thread B: lock(m2) → lock(m1)
// Chacun attend l'autre → deadlock
// Solution : lock ordering, std::lock()

Async (I/O non bloquant)

  • Event loop : boucle qui attend des événements et exécute des callbacks
  • Approches :
    • Callbacks : Node.js (callback hell)
    • Promises : chaînage .then()
    • Async/await : syntaxe synchrone pour code async
    • Coroutines : asyncio (Python), tokio (Rust)
    • Fibers : green threads (Ruby, Java Loom)

I/O Models (Unix) :

  1. Blocking I/O : read() bloque jusqu'à données
  2. Non-blocking I/O : read() retourne EAGAIN
  3. I/O Multiplexing : select/poll/epoll
  4. Signal-driven I/O : SIGIO
  5. Asynchronous I/O : aio_read(), io_uring

io_uring (Linux 5.1+) :

  • File d'attente de soumission (SQ) et de complétion (CQ)
  • Zero-copy, system call avoidance
  • Bests performances pour I/O-bound workloads

4. Concurrence et Parallélisme

Concurrence vs Parallélisme

  • Concurrence : gérer plusieurs tâches (logique) — 1 cœur
  • Parallélisme : exécuter plusieurs tâches simultanément (physique) — N cœurs

Modèles de concurrence

  1. Preemptive (threads OS) : scheduler noyau décide des switchs
  2. Cooperative (goroutines, coroutines) : tâches yield explicitement
  3. Actor model (Erlang, Akka) : acteurs communiquent par messages
  4. CSP (Go, Clojure core.async) : channels + goroutines
  5. STM (Haskell, Clojure) : Software Transactional Memory

Amdahl's Law

Speedup = 1 / ((1 - P) + P/N)
Où P = proportion parallélisable, N = nombre de cœurs

Limite : même avec N→∞, speedup ≤ 1/(1-P)

Gustafson's Law

Scaled Speedup = (1 - P) + N*P

Plus optimiste : les problèmes grandissent avec les ressources.

5. Gestion Mémoire

Hiérarchie mémoire

Registers        ~1ns        ~1KB
L1 Cache         ~2ns        ~32KB
L2 Cache         ~7ns        ~256KB
L3 Cache         ~15ns       ~8MB
RAM              ~80ns       ~32GB
SSD              ~100μs      ~1TB
HDD              ~10ms       ~10TB
Network          ~50ms       ∞

Virtual Memory

  • Page table : mapping mémoire virtuelle → physique
  • TLB : Translation Lookaside Buffer (cache de page table)
  • Page fault : accès à une page non mappée (lente !)
  • MMU : Memory Management Unit (hardware)

Memory allocators

  • malloc/free : glibc (ptmalloc), jemalloc, tcmalloc, mimalloc
  • Arena : zones mémoire pour réduire contention multi-thread
  • Slab allocator : pour objets de taille fixe (noyau Linux)

Garbage Collection

  • Reference counting : Python, Swift (mais cycles !)
  • Mark & Sweep : marque objets vivants, sweep morts (Go, Java CMS)
  • Copying : copie objets vivants dans semi-espace (Java parallel)
  • Generational : young/old generation (Java G1, ZGC)
  • Concurrent : pas de stop-the-world (Go, Java ZGC/Shenandoah)

Memory Leaks in GC languages

  • Références circulaires non détectées (ref counting)
  • Caches sans éviction
  • Closures capturant trop de scope
  • Event listeners non déréférencés

6. DNS

Hiérarchie DNS

Root (.) → 13 serveurs racines (a.root-servers.net → m.root-servers.net)
  ├── TLD (.com, .org, .fr, .io, ...)
  │   ├── Authoritative (example.com)
  │   │   ├── A/AAAA records (IPv4/IPv6)
  │   │   ├── CNAME (alias)
  │   │   ├── MX (mail exchange)
  │   │   ├── TXT (SPF, DKIM, DMARC)
  │   │   └── NS (name servers)

Résolution DNS

  1. Client → Resolver local (/etc/resolv.conf)
  2. Resolver → Root server → TLD server → Authoritative
  3. Résultat : cache local + TTL

DNS Record Types :

TypeUsageExemple
AIPv4192.0.2.1
AAAAIPv62001:db8::1
CNAMEAliaswww → example.com
MXMailmail.example.com
TXTTextev=spf1 include:_spf.google.com
NSServeur DNSns1.example.com
PTRReverse192.0.2.1 → hostname
SRVService_sip._tcp.example.com

DNS Propagation : TTL (60s-86400s), négative caching (NXDOMAIN)

DNS Security : DNSSEC (signatures), DoH/DNS over HTTPS, DoT/DNS over TLS

7. Load Balancing

Algorithmes

AlgoDescriptionUsage
Round RobinDistribution cycliqueSimple, prévisible
Least ConnectionsÀ la plus petite chargeSessions longues
IP HashHachage IP clientSession persistence
RandomAléatoireTests
WeightedPoids configurableHétérogène
GeographicPar régionLatence minimale
Consistent HashingAnneau de hachageCache, scaling

Reverse Proxy

Client → [Nginx/Caddy/Traefik] → App Server 1
                                  App Server 2
                                  App Server 3

Fonctions : SSL termination, caching, compression, rate limiting, WAF, static files

Layer 4 vs Layer 7

CritèreL4 (TCP/UDP)L7 (HTTP/gRPC)
DécisionIP + portURL, headers, cookies
PerformanceTrès hauteHaute
FeaturesLimitéeRouting intelligent
ExemplesHAProxy, AWS NLBNginx, Traefik, AWS ALB

Health Checks

  • Passive : détection d'erreurs sur le trafic réel (5xx consecutifs → retrait)
  • Active : requêtes périodiques /health (interval, timeout, threshold)

Connection Draining

  1. Serveur marqué "draining"
  2. Nouvelles connexions redirigées ailleurs
  3. Connexions existantes ont un timeout (graceful shutdown)
  4. Une fois vide, serveur retiré

Références

  • RFC 7230-7235 (HTTP/1.1), RFC 7540 (HTTP/2), RFC 9114 (HTTP/3)
  • TCP/IP Illustrated (Stevens)
  • Computer Networking: A Top-Down Approach (Kurose & Ross)
  • The Linux Programming Interface (Kerrisk)
  • System Performance (Gregg)