Happy Eyeballs

Happy Eyeballs (RFC 8305, версия 2) — алгоритм, которым клиент параллельно пробует IPv4 и IPv6 (и разные IP-адреса от DNS) и использует то, что подключилось первым. Устраняет знаменитую проблему «сайт медленно грузится» когда IPv6 работает криво.

Проблема которую решает

DNS вернул A + AAAA. Клиент раньше делал так:

  1. Пробует IPv6 (AAAA).
  2. Таймаут коннекта (60 секунд).
  3. Фолбэк на IPv4 (A).

Юзер сидит и смотрит на белый экран 60 секунд. Не «happy».

Как работает Happy Eyeballs v2

  1. Одновременно резолвим A и AAAA. Что ответило первым — начинаем использовать.
  2. Первую попытку делаем на IPv6 (если есть).
  3. Через Resolution Delay (~50 мс) если IPv6 не соединился — начинаем параллельно на IPv4.
  4. Через Connection Attempt Delay (~250 мс) если ни один не соединился — переходим к следующему адресу из результата DNS.
  5. Первый успешный TCP-handshake (или QUIC 0-RTT) — используется. Остальные попытки RST-ятся.

В итоге медленный IPv6 не заставляет юзера ждать — параллельный IPv4 быстро подхватит.

Задержки по стандарту

ПараметрЗначениеЧто означает
Resolution Delay50 мсЗадержка перед стартом IPv4-попытки после IPv6
Connection Attempt Delay250 мс (реком. 100-2000)Между попытками к разным IP
Minimum Connection Attempt Delay100 мсНижний предел
Maximum Connection Attempt Delay2000 мсВерхний предел

Address sorting

В RFC 6724 определён порядок сортировки адресов от DNS. Happy Eyeballs использует его, но с обязательным чередованием семейств (IPv6, IPv4, IPv6, IPv4...) чтобы не тратить весь пул попыток на одно семейство если оно сломано.

Happy Eyeballs для протоколов

RFC 8305 определяет базово только IPv4/IPv6. Позже расширения:

Реализации

Как проверить

# Заставить curl подождать 500мс перед IPv4-фолбэком
curl --happy-eyeballs-timeout-ms 500 https://example.com

# Только IPv6
curl -6 https://example.com

# Посмотреть какой семейством ходит браузер
# В DevTools → Network → выбрать запрос → Remote Address

Побочный эффект — двойная нагрузка

Клиент открывает две попытки, одна из них потом RST. Крупные сервисы (Google, Cloudflare) получают ~5-10% лишних SYN-пакетов. С их масштабом — ощутимо, но приемлемая цена за user experience.

См. также