Проксирование из коробки: сравнительный анализ HAProxy, Envoy, Nginx, Caddy и Traefik
Всем привет, меня зовут Стас, я техлид в Mish Product Lab.
Тема возникла не просто так: внутри команды у нас было немало споров и дискуссий о том, какой инструмент для проксирования и терминации SSL лучше использовать в различных ситуациях. Изначально все наши гипотезы были основаны больше на личных предпочтениях, чем на реальных данных. Мы долго спорили, надеясь, что истина будет где-то рядом с нашими любимыми решениями. Но в итоге пришли к выводу, что единственный способ получить действительно объективный ответ — это протестировать и сравнить различные варианты на практике.
Именно так родилась идея провести сравнительный анализ производительности HAProxy, Envoy, Nginx, Caddy и Traefik с поддержкой SSL/TLS. Мы хотели понять, какой из инструментов «из коробки» предоставляет наилучшую производительность и минимальные накладные расходы, особенно при обработке SSL-трафика, который, как известно, требует дополнительных ресурсов из-за шифрования и дешифрования.
Важно подчеркнуть, что наша задача не заключалась в поиске идеального или максимально оптимизированного решения. Для глубоких и тонких настроек всегда лучше обратиться к DevOps-инженерам, которые обладают необходимыми компетенциями и понимают нюансы каждого инструмента. Нашей целью было скорее провести «полевые испытания» и составить заметки, которые могли бы помочь нам самим и будущим поколениям разработчиков быстрее принимать решения на основе хотя бы приблизительных ориентиров.
Итак, мы готовы поделиться нашими наблюдениями и результатами тестов.
Работаем с тестовыми стендами
Для обеспечения объективности и прозрачности тестирования мы выбрали три отдельных стенда, каждый из которых отвечал за свою часть сценария нагрузки. Разделение ролей стендов было принципиально важным для минимизации возможных взаимных влияний и искажений результатов. Это позволило максимально точно зафиксировать поведение каждого инструмента и компонента инфраструктуры.
Все тестовые стенды были размещены в одной сети, что гарантировало стабильную и предсказуемую сеть без значительных задержек. Никаких настроек ядра, голые системы.
Тестовый стенд 1 (K6) предназначался для генерации и управления трафиком при помощи инструмента K6. Его ресурсы (32 vCPU, 128 ГБ RAM) обеспечивали возможность генерировать существенную нагрузку и давала нам уверенность в том, что сам инструмент генерации не станет узким местом.
Тестовый стенд 2 (Web) был основным объектом тестирования. Здесь были установлены различные инструменты для проксирования (HAProxy, Envoy, Nginx, Caddy, Traefik) и мониторинг штатными средствами хостера. Это позволило нам не только протестировать производительность каждого решения, но и подробно отслеживать потребление ресурсов. Ресурсы 32 vCPU, 128 ГБ RAM.
Тестовый стенд 3 (Backend) выполнял роль типичного приложения (backend), написанного на Golang, которое должно было принимать и обрабатывать запросы, проходящие через прокси. Ресурсы 8 vCPU, 32 ГБ RAM.
Такое разделение ролей и ресурсов дало возможность получить максимально чистые и объективные данные о производительности каждого инструмента.
Версии веб серверов
haproxy 3.1.6envoy 1.34.0-devnginx 1.27.4traeffik 3.3.5caddy 2.9.1
Работаем с бэкэндом
Сервис делали на Golang, для обработки запросов использовали fasthttp — никаких излишеств.
Запускаем стресс-тест на этот сервис: 50 000 rps, 1 минута
K6 (генерация трафика и проверка ответа, http code и body):
Результат — тест выполнен успешно.Максимальная задержка — max=47.52ms
Пропускная способность — 49964.433616/s
Настройка и тестирование проксирования
K6 (генерация трафика и проверка ответа, http code и body):
Получаем сертификат:
Сертификаты появятся тут:
Теперь совместим их — это нужно для HAProxy:
HAProxy
Начать решили именно с HAProxy, так как он позволяет максимально быстро и эффективно протестировать работоспособность архитектуры без сложной предварительной настройки инфраструктуры.
docker-compose.yml
HAProxy запускается через Docker Compose, что позволяет легко воспроизводить окружение на разных серверах и машинах разработчиков.
Порты 80 и 443 прокидываются наружу, то есть сервис явно ориентирован на обработку HTTP и HTTPS-запросов.
SSL-сертификат Let’s Encrypt подключается напрямую через volume, таким образом сервис сразу готов к работе в защищённом режиме (HTTPS).
haproxy.cfg
HAProxy настроен в режиме http, и весь трафик, поступающий на порт 443, перенаправляется в backend-сервис, указанный в конфигурации (10.0.0.8:8080).
Запускаем созданный выше сценарий
Нагрузка на систему
Основные выводы:
CPU
Загрузка до ~900% (9 ядер), стабильна весь тест → CPU справился.
K6 Test Summary
RPS (успешные): 49,728 / сек
Макс. задержка: 1.07s
Время ответа p(95): 1.16 ms
Дропнутые итерации: 16,192 (≈0.5%)
Ошибки: 0% (http_req_failed = 0.00%)
Объём данных:
Получено: 374 MB (6.2 MB/s)
Отправлено: 108 MB (1.8 MB/s)
VUs использовано: 28–357
Макс. допустимо: 1293 VUs
Отличная производительность, минимальные задержки, всё стабильно.
Envoy
Высокопроизводительный прокси-сервер и балансировщик нагрузки, разработанный компанией Lyft, поддерживающий динамическое конфигурирование, observability и множество современных протоколов.
docker-compose.yml
Envoy разворачивается через Docker Compose для простоты повторяемости окружения.
Используется сертификат Let’s Encrypt, напрямую подключённый в конфигурацию.
Порты 80 и 443 открываются для обработки входящего трафика.
envoy.yaml
- Запросы, поступающие на домен test-backend.mish.design, перенаправляются на backend-сервис по адресу 10.0.0.4:8080 с балансировкой по алгоритму round-robin.
- Envoy автоматически терминирует TLS-соединения и маршрутизирует трафик по HTTP.
Запускаем созданный выше сценарий
Нагрузка на систему
Основные выводы:
CPU
- Загрузка до ~1600% → использовано до 16 ядер, держалось стабильно.
K6 Test Summary
- RPS (успешные): 49,749 / сек
- Ошибки: 0%
- Дропнутые итерации: 14,895 (≈0.5%)
- Время ответа p(95): 3.34 ms
- Макс. задержка: 132 ms
- Объём данных:Получено: 597 MB (9.9 MB/s)Отправлено: 344 MB (5.7 MB/s)
- VUs использовано: 49–291
- Макс. допустимо: 1262 VUs
Отличная производительность, минимальные задержки, всё стабильно.
Traefik
Современный обратный прокси и балансировщик нагрузки с встроенной поддержкой автоматической выдачи и обновления SSL-сертификатов через Let’s Encrypt. Он разработан для динамической работы с контейнерными средами, такими как Docker и Kubernetes.
docker-compose.yml
- Запуск через Docker Compose — Traefik работает как отдельный сервис в контейнере.
- Порты 80 и 443 — открыт для приёма HTTP и HTTPS-трафика.
- Сертификаты Let’s Encrypt — полностью автоматическая выдача и хранение сертификатов.
dynamic_conf.yml
- Запросы на test-backend.mish.design по HTTPS идут на backend-сервис по адресу http://10.0.0.8:8080.
- Используется entryPoint websecure (порт 443).
- Балансировка выполняется на уровне Traefik.
Запускаем созданный выше сценарий
Нагрузка на систему
Основные выводы:
CPU
- Загрузка до ~3000% → задействовано ~30 ядер.
Network Traffic
- Периоды падения, из-за ошибок и дропов.
K6 Test Summary (Traefik)
- Успешные запросы: 4,659 RPS (в 10 раз ниже цели)
- Ошибки: ❌ 32.84%
- Дропы: ❌ 2,088,749 итераций (‼ огромный уровень отказов)
- p(95) ответа: ❌ 8.46 сек
- Максимальная задержка: 32.98 сек (!)
- Передано:Получено: 126 MB (1.6 MB/s)Отправлено: 24 MB (308 KB/s)
- VUs: до 29,243 → рост числа VUs указывает на тяжёлую деградацию под нагрузкой
❗ Вывод:
- Traefik не справился с 50k RPS.
- Наблюдаются:Массовые дропы итерацийВыс��кие задержки
- Требуется оптимизация, либо он не подходит для такого уровня нагрузки в текущей конфигурации.
Nginx
Классический веб-сервер и обратный прокси, известный своей стабильностью, высокой производительностью и минимальным потреблением ресурсов. Один из самых популярных инструментов для терминации TLS, балансировки нагрузки и проксирования трафика
docker-compose.yml
- Запуск через Docker Compose — контейнер с NGINX разворачивается быстро и удобно.
- Открыты порты 80 (HTTP) и 443 (HTTPS) для обработки входящего трафика.
- Подключены сертификаты от Let’s Encrypt для обеспечения HTTPS.
default.conf
- Прописаны все основные заголовки для правильной передачи оригинального IP и схемы клиента на backend.
- worker_processes auto; — количество воркеров подстраивается под доступные ядра.
- worker_rlimit_nofile 100000; — увеличен лимит на количество открытых файлов (важно при высоких нагрузках).
- worker_connections 5000; и multi_accept on; — рассчитано на большое количество одновременных соединений.
- Используется epoll — эффективный режим для Linux-систем с высоким количеством соединений.
Запускаем созданный выше сценарий
Нагрузка на систему
Основные выводы:
CPU
- Загрузка до ~3000% → задействовано ~30 ядер.
Network Traffic
- Трафик стабильнее, чем у Traefik, но ниже, чем у Envoy.
K6 Test Summary (NGINX)
- Успешные RPS: 9,158 / сек (х2 выше Traefik, но всё ещё ниже цели)
- Ошибки: ❌ 10.2% (http_req_failed)
- Дропы: ❌ 1,154,367 итераций
- p(95) задержка: ❌ 3.82 сек, медиана 1.73 сек
- Макс. задержка: 30 сек (таймаут)
- Передано:Получено: 231 MB (2.6 MB/s)Отправлено: 95 MB (1.1 MB/s)
- VUs: до 29,354 → высокая нагрузка на уровне Traefik.
⚠ Вывод:
- NGINX работает лучше Traefik, но сильно уступает HAProxy и Envoy.
- Присутствуют таймауты, высокие задержки и дропы.
Caddy
Это современный веб-сервер и обратный прокси с нативной поддержкой HTTPS и автоматического получения сертификатов от Let’s Encrypt. Главные преимущества Caddy — простота конфигурации, автоматическое управление TLS и минимальные усилия по обслуживанию.
docker-compose.yml
- Запуск через Docker Compose — контейнерный запуск с удобным управлением жизненным циклом.
- Открыты порты 80 и 443 (включая 443/udp для HTTP/3).
- Используется Caddyfile — минималистичная и читаемая конфигурация.
Caddyfile
- Caddy автоматически берёт и обновляет сертификаты Let’s Encrypt без дополнительных скриптов и настроек.
- Логирование настроено на уровень ERROR для минимальной нагрузки на диск.
- Проксирование запросов на backend-сервис по адресу http://10.0.0.4:8080.
Запускаем созданный выше сценарий
Нагрузка на систему
Основные выводы:
CPU
- Загрузка до ~3000% → задействовано ~30 ядер.
Network Traffic
- Пик входящего трафика: ~6–7 MBps, исходящего: ~3–4 MBps
- Колебания присутствуют, особенно в начале — возможны ошибки или нестабильная отдача.
K6 Test Summary (Caddy)
- Успешные RPS: 3,354 / сек → в 15 раз ниже цели
- Ошибки: ❌ 35.87% (http_req_failed)
- Дропы: ❌ 1,861,627 итераций
- p(95) задержка: ❌ 17.03 сек (!), медиана ≈0.4 сек
- Макс. задержка: 34.92 сек
- Трафик:Получено: 104 MB (1.2 MB/s)Отправлено: 23 MB (250 KB/s)
- VUs: до 29,170 — почти на пределе лимита
❌ Вывод:
- Caddy не выдерживает нагрузку в 50k RPS
- Большая доля ошибок, дропов и задержек
- Работает хуже, чем NGINX и Traefik, ближе к антирекорду
Итоги
✅ HAProxy — лидер по стабильности
- Уверенный лидер по результатам тестов: стабильно держит 50 000 rps при минимальной нагрузке на CPU. Прост в запуске и конфиге.
🟢 Envoy — почти наравне с HAProxy
- Нагрузка на CPU выше, но приемлемая. Удобен в сценариях, где нужны гибкие настройки маршрутизации.
🟡 NGINX — середняк
- Нужен fine-tuning или другой режим работы
- Пропускная способность в 5 раз ниже ожидаемой
- Аномальная нагрузка на CPU
🔴 Traefik — нестабилен
- Почти 33% ошибок, сильные дропы, p95 = 8.5 сек.
- Пропускная способность в 5 раз ниже ожидаемой
- Аномальная нагрузка на CPU
🔻 Caddy — худший результат
- Самые высокие задержки (p95 = 17 сек), ошибки 36%, дропов >1.8 млн.
- Аномальная нагрузка на CPU
- Явно не справляется с такой нагрузкой в дефолтной конфигурации.
Что важно понять из результатов?
- HAProxy и Envoy — лучшие выборы, если нужна готовая к бою система без плясок с бубном.
- Traefik, NGINX, Caddy — требуют дополнительной настройки и оптимизации для высоконагруженных сценариев.
Для кого подойдёт и зачем всё это использовать?
Когда можно брать HAProxy или Envoy:
- Когда нужен стабильный и производительный балансировщик «здесь и сейчас».
- Минимальные усилия на настройку — запустил и работает.
Когда стоит смотреть на Traefik / NGINX / Caddy:
- Для небольших и средних проектов, где нагрузки ниже и можно позволить себе чуть сложнее конфиг или доработку.
- Если в команде есть человек, который умеет настраивать и оптимизировать эти инструменты под конкретные задачи.
Update
По просьбам из комментариев дополнительные тесты NGINX
Тест №1
keepalive 4;Без multi_accept
Тест №2
keepalive 4;C multi_accept
Тест №3
Исходный конфиг + тюнинг SSL
Спасибо что дочитали до конца ;-)
Подписывайтесь на Mish в Telegram, у нас много полезного и красивого: