Обновить

Решаем архитектурную проблему nginx с HTTP/3: опыт Angie и магия eBPF

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели8.2K
Всего голосов 25: ↑24 и ↓1+26
Комментарии9

Комментарии 9

Спасибо за подробную статью. Нужно будет потестировать производительность на свежей версии Angie. Несколько месяцев назад я делал тестовые переключения на HTTP/3 и неизменно наблюдал падение отклика веб сервера. Увеличивалась метрика TTFB (Time To First Byte) и за ней Time to Start Render. Внимательно смотрел на результаты и сравнивал. HTTP/3 даёт по всем параметрам результаты не хуже HTTP/2, а где-то даже лучше. Total Connection Time у h3 неизменно ниже, загрузка всех элементов чуть быстрее, но Time to First Byte, за который по идее отвечает непосредственно сервер, всегда у h3 был выше и из-за этого ехали все остальные метрики, так как и отрисовка, и полная загрузка начинали отставать. Для себя тогда решил, что пока овчинка выделки не стоит.

Если тестирование происходило не в собственной сети, то во всех этих экспериментах и наблюдая различные аномалии нужно учитывать возможное влияние ТСПУ у провайдеров. Какое влияние они оказывают на другой протокол транспорта и как себя ведут в этом случае, пожалуй, известно только их разработчикам.

Я тоже в первую очередь об этом подумал. Тесты были не синтетические, а на реальном сайте в интернете. Но так как мне нужно было увидеть практический смысл перехода на другой протокол, посчитал, что смысла делать синтетические тесты в лаборатории нет.

Плюс нужно учитывать, что если не была правильно настроена HTTPS‑запись в DNS, то браузеры сперва обычно пробуют подключаться по HTTP/1-2 и только затем, узнав о поддержке HTTP/3 из заголовков, переходят на него для загрузки остальных ресурсов. Это может также сказываться на учете метрик.

В реальных условиях новые подключения будут по HTTP/2 и только после нескольких перых запросов браузер переходит на HTTP/3. Чистые сессии HTTP/3 возможны для повторных посещений (кэш заголовка Alt-Svc) или при использовании HTTPS-записей в DNS (и то, не всегда).

Я всё это учитывал. В локальном webpagetest это нормально отслеживается.

Как-то понадобилось, чтобы в служебном виртуальном сервере только один (произвольный) воркер отвечал на клиентские запросы. Для этого в кастомном модуле использовал классический BPF (не eBPF).

    struct sock_filter  bpf_code[] = { { 0x6, 0, 0, 0x00000000 } };
    struct sock_fprog   bpf = { .len = 1, .filter = bpf_code };

    // ...

    // в коде инициализации модуля:

            if (scf->single_listener) {
                if (!ls[i].reuseport) {
                    ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                                  "single listener \"%V\" must use reuseport",
                                  &ls[i].addr_text);
                    return NGX_ERROR;
                }

                if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF,
                               (const void *) &bpf, sizeof(bpf))
                    == -1)
                {
                    ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                                  "setsockopt(SO_ATTACH_REUSEPORT_CBPF) %V "
                                  "failed", &ls[i].addr_text);
                }
            }

bpf_code - это байт код BPF.

Применение:

    server {
        listen          8100 reuseport;
        server_name     stats;

        single_listener on;

    # ...

    }

А в оригинальный nginx правки отправили или окончательно рассорились?

Я чуть подробнее на этом останавливался в комментарии к одной из прошлых статей. Никто не ссорился, просто там корпоративная политика заключается в том, что нужно делать вид, что нас не существует. Поэтому нет большого смысла пытаться пробить лбом стену с одной стороны, а с другой то и желания бесплатно работать на Ф5 - тоже особо нет.

P.S. Если вдруг политика у них поменяется, то они всегда могут заглянуть к нам в репозиторий и замерджить соответствующие правки, т.к. лицензии одинаковые, позволяют, только копирайт нужно будет указать. Однако, они не мерджат даже багфиксы из freenginx и похоже не смотрят туда, оставляя баги в nginx, которые уже были исправлены у других.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации