Обзор транспортного уровня
Транспортный уровень (L4 в модели OSI) отвечает за доставку данных между приложениями на разных хостах. Два основных протокола -- TCP и UDP -- представляют фундаментальный компромисс между надёжностью и скоростью.
┌─────────────────────────────────────────────────┐
│ Application (HTTP, DNS) │
├─────────────────────────────────────────────────┤
│ Transport (TCP / UDP / QUIC) │
├─────────────────────────────────────────────────┤
│ Network (IP) │
├─────────────────────────────────────────────────┤
│ Data Link + Physical │
└─────────────────────────────────────────────────┘
Зачем это знать для System Design
- Выбор TCP vs UDP определяет латентность и надёжность системы
- Понимание congestion control помогает при проектировании real-time систем
- QUIC меняет правила игры для HTTP/3 и современных приложений
- На собеседовании часто спрашивают: «Почему вы выбрали TCP/UDP для этого компонента?»
TCP (Transmission Control Protocol)
Ключевые свойства
| Свойство | Описание |
|---|---|
| Надёжность | Гарантированная доставка всех пакетов |
| Порядок | Данные приходят в правильном порядке |
| Соединение | Требуется установка соединения (handshake) |
| Flow control | Отправитель не перегружает получателя |
| Congestion control | Адаптация к пропускной способности сети |
| Full-duplex | Одновременная передача в обе стороны |
Структура TCP-сегмента
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Source Port (16) │ Destination Port (16) │
├───────────────────────────────────┼────────────────────────────────┤
│ Sequence Number (32) │
├───────────────────────────────────────────────────────────────────┤
│ Acknowledgment Number (32) │
├──────┬───────┬─┬─┬─┬─┬─┬─┬───────────────────────────────────────┤
│Offset│Reserv │U│A│P│R│S│F│ Window Size (16) │
│ (4) │ (3) │R│C│S│S│Y│I│ │
│ │ │G│K│H│T│N│N│ │
├──────┴───────┴─┴─┴─┴─┴─┴─┼───────────────────────────────────────┤
│ Checksum (16) │ Urgent Pointer (16) │
├───────────────────────────┴───────────────────────────────────────┤
│ Options (variable) │
├───────────────────────────────────────────────────────────────────┤
│ Data │
└───────────────────────────────────────────────────────────────────┘
Трёхстороннее рукопожатие (3-Way Handshake)
Установка TCP-соединения требует 3 пакетов -- 1 RTT (Round-Trip Time) до начала передачи данных.
Клиент Сервер
│ │
│──── SYN (seq=x) ────────────────────►│
│ │ Клиент хочет соединение
│◄──── SYN-ACK (seq=y, ack=x+1) ──────│
│ │ Сервер согласен
│──── ACK (seq=x+1, ack=y+1) ────────►│
│ │ Соединение установлено
│◄═══════ Data Transfer ══════════════►│
│ │
Закрытие соединения (4-Way Teardown):
Клиент Сервер
│──── FIN ────────────────────────────►│
│◄──── ACK ────────────────────────────│
│◄──── FIN ────────────────────────────│
│──── ACK ────────────────────────────►│
│ │
│ (TIME_WAIT: 2*MSL ≈ 60 сек) │
Для System Design: TIME_WAIT может стать проблемой при большом количестве короткоживущих соединений. Решения: connection pooling,
SO_REUSEADDR, keep-alive.
Flow Control (Управление потоком)
TCP использует механизм скользящего окна (sliding window), чтобы отправитель не перегрузил получателя.
Получатель объявляет Window Size = 4 сегмента
Отправитель: [1][2][3][4] 5 6 7 8 9 10
───────────
Окно отправки (можно отправить без ACK)
После ACK на 1,2:
Отправитель: 1 2 [3][4][5][6] 7 8 9 10
───────────
Окно сдвинулось вправо
Window Scaling: По умолчанию Window Size -- 16 бит (максимум 65535 байт). Опция Window Scale позволяет увеличить до 1 ГБ -- критично для высокоскоростных сетей.
Congestion Control (Управление перегрузкой)
TCP адаптирует скорость отправки к состоянию сети. Основные алгоритмы:
Slow Start + Congestion Avoidance
Congestion Window (cwnd)
^
│ * * * * * ← Congestion Avoidance
│ * (линейный рост)
│ *
│ * ← ssthresh (порог)
│ *
│ * ← Slow Start
│ * (экспоненциальный рост)
│*
└──────────────────────► Время
- Slow Start: cwnd начинается с 1 MSS, удваивается каждый RTT
- Congestion Avoidance: после ssthresh cwnd растёт на 1 MSS за RTT
- При потере пакета: ssthresh = cwnd/2, cwnd = 1 (TCP Tahoe) или cwnd = ssthresh (TCP Reno)
Современные алгоритмы
| Алгоритм | Подход | Использование |
|---|---|---|
| CUBIC | Кубическая функция роста cwnd | Linux по умолчанию |
| BBR (Google) | Оценка bandwidth и RTT | Google, YouTube |
| BBR v2 | Улучшенная fairness | Новые системы |
| DCTCP | ECN-aware для дата-центров | Внутри дата-центров |
Для System Design: BBR значительно улучшает throughput на каналах с высоким RTT и потерями. Google наблюдал рост пропускной способности на 2-25% после перехода на BBR.
TCP Fast Open (TFO)
Позволяет отправлять данные уже в SYN-пакете, экономя 1 RTT при повторных соединениях.
Первое соединение (получаем cookie):
Клиент ── SYN ──────────────────────► Сервер
Клиент ◄── SYN-ACK + Cookie ─────── Сервер
Клиент ── ACK + Data ──────────────► Сервер
Последующие соединения (0-RTT):
Клиент ── SYN + Cookie + Data ─────► Сервер ← Данные сразу!
Клиент ◄── SYN-ACK + Data ───────── Сервер
UDP (User Datagram Protocol)
Ключевые свойства
| Свойство | Описание |
|---|---|
| Ненадёжность | Нет гарантии доставки |
| Без порядка | Пакеты могут прийти в любом порядке |
| Без соединения | Нет handshake |
| Минимальный overhead | Заголовок всего 8 байт |
| Быстрота | Нет задержки на установку соединения |
| Broadcast/Multicast | Поддержка групповой рассылки |
Структура UDP-датаграммы
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Source Port (16) │ Destination Port (16) │
├───────────────────────────────────┼────────────────────────────────┤
│ Length (16) │ Checksum (16) │
├───────────────────────────────────┴────────────────────────────────┤
│ Data │
└───────────────────────────────────────────────────────────────────┘
TCP заголовок: 20-60 байт vs UDP заголовок: 8 байт
Когда UDP лучше TCP
- Потеря пакета допустима: видеозвонки, стриминг, онлайн-игры
- Скорость важнее надёжности: DNS-запросы, NTP
- Multicast нужен: IPTV, service discovery
- Приложение реализует свою надёжность: QUIC, DTLS
TCP vs UDP: Сравнение
| Критерий | TCP | UDP |
|---|---|---|
| Соединение | Да (3-way handshake) | Нет |
| Надёжность | Гарантированная доставка | Best-effort |
| Порядок | Гарантирован | Не гарантирован |
| Overhead заголовка | 20-60 байт | 8 байт |
| Flow control | Да | Нет |
| Congestion control | Да | Нет |
| Скорость | Ниже (из-за overhead) | Выше |
| Broadcast | Нет | Да |
| Применение | Web, API, email, файлы | Видео, игры, DNS, IoT |
QUIC
QUIC -- протокол транспортного уровня от Google, работающий поверх UDP. Стал основой HTTP/3.
Архитектура QUIC
┌─────────────────────────────────────────┐
│ HTTP/3 │
├─────────────────────────────────────────┤
│ QUIC │
│ ┌────────┬────────┬────────────────┐ │
│ │ Stream │ Stream │ Connection │ │
│ │ Mux │ Ctrl │ Migration │ │
│ ├────────┴────────┤ │ │
│ │ TLS 1.3 │ 0-RTT │ │
│ │ (встроенный) │ Resumption │ │
│ ├─────────────────┴────────────────┤ │
│ │ Loss Detection + Recovery │ │
│ │ Congestion Control │ │
│ └──────────────────────────────────┘ │
├─────────────────────────────────────────┤
│ UDP │
├─────────────────────────────────────────┤
│ IP │
└─────────────────────────────────────────┘
Ключевые преимущества QUIC
1. Быстрое установление соединения:
TCP + TLS 1.3: 1 RTT (handshake) + 1 RTT (TLS) = 2 RTT
QUIC первое: 1 RTT (QUIC + TLS объединены)
QUIC повторное: 0 RTT (кешированные параметры)
2. Устранение Head-of-Line Blocking:
TCP: Потеря пакета в потоке A блокирует потоки B и C
Stream A: [1][X][3] ← пакет 2 потерян
Stream B: [1][2][3] ← ЗАБЛОКИРОВАН (ждёт A)
Stream C: [1][2] ← ЗАБЛОКИРОВАН
QUIC: Потоки независимы
Stream A: [1][X][3] ← ждёт только A
Stream B: [1][2][3] ← доставлено ✓
Stream C: [1][2] ← доставлено ✓
3. Connection Migration: При смене Wi-Fi на LTE TCP-соединение разрывается (смена IP). QUIC использует Connection ID и продолжает работу.
Выбор протокола в System Design
Дерево решений
Нужна гарантированная доставка?
├── ДА → Критична низкая латентность?
│ ├── ДА → QUIC / HTTP/3
│ └── НЕТ → TCP / HTTP/1.1-2
└── НЕТ → Допустимы потери данных?
├── ДА → UDP (видео, аудио, игры)
└── НЕТ → Надёжность поверх UDP (QUIC, custom protocol)
Примеры из реального мира
| Система | Протокол | Причина |
|---|---|---|
| Web API (REST/GraphQL) | TCP (HTTP) | Надёжность, стандартность |
| Видеозвонки (Zoom) | UDP + SRTP | Низкая латентность, потеря кадра ОК |
| Онлайн-игры | UDP + custom | Позиция игрока нужна сейчас, а не через RTT |
| DNS-запросы | UDP (порт 53) | Маленький запрос, быстрый ответ |
| DNS over HTTPS | TCP (HTTPS) | Приватность важнее скорости |
| YouTube стриминг | QUIC (HTTP/3) | Мультиплексирование, 0-RTT |
| Базы данных | TCP | Надёжность транзакций |
| IoT телеметрия | UDP / MQTT | Экономия ресурсов |
| Микросервисы (gRPC) | TCP (HTTP/2) | Стриминг, надёжность |
Важные числа для собеседования
| Метрика | Значение |
|---|---|
| TCP handshake | 1 RTT (~1-100 мс в зависимости от расстояния) |
| TLS 1.3 handshake | 1 RTT |
| QUIC handshake (первое) | 1 RTT |
| QUIC handshake (повторное) | 0 RTT |
| TCP заголовок | 20-60 байт |
| UDP заголовок | 8 байт |
| MSS (Max Segment Size) | 1460 байт (при MTU 1500) |
| Начальный cwnd | 10 MSS (~14.6 KB) |