Когда я писал статью про HAProxy, у меня возникла идея сравнить его с другим популярным proxy-сервером, например с Envoy. Но тогда мне показалось, что простое сравнение в виде таблицы или пары абзацев будет неинформативным — и я решил сделать полноценный разбор в отдельной статье. Если вам интересно — добро пожаловать! Здесь рассмотрены не все возможности каждого решения, но ключевые — те, которые действительно важны на практике.
Сегодня я разберу три популярных прокси, сравню их и расскажу: что, где и когда лучше применять. Под «популярными» я имею в виду те, с которыми работал сам и изучил их устройство «под капотом». Прокси существует гораздо больше, но о других говорить не буду — либо не копал глубоко, либо знаю слишком мало, чтобы включать их в разбор. Отдельно отмечу важность документации: если она запутана или неполна, приходится гадать, что и где настраивать, а это быстро отбивает желание работать с инструментом.
HAProxy 3.3, NGINX 1.29 и Envoy 1.35 — три open source-прокси с разной архитектурой и моделью управления. Enterprise-версии рассматривать не буду — капитализм делает свое дело: серьёзных отличий почти нет, а вот в OSS-вариантах есть что сравнить — в ряде моментов конкуренция пошла на пользу.
Итак, начинаем. Рассматриваем самые свежие релизы на дату публикации.
План разбора:
Цель и версии (только open source, последние доступные stable-ветки)
Архитектура (Модель потоков/процессов, event-loop, статическая vs динамическая конфигурация (xDS, Data Plane API).
Поддерживаемые протоколы L4/L7 (HTTP/1.1, HTTP/2, HTTP/3/QUIC, gRPC, WebSocket, TCP/UDP)
Балансировка и маршрутизация (Алгоритмы round-robin, least-conn, hash, L7-маршруты, аффинити)
Надежность и отказоустойчивость (Health-check, retries, circuit-breaking, rate-limiting)
Наблюдаемость (Метрики Prometheus/StatsD, логи, OpenTelemetry/Jaeger, трассировка)
Безопасность (TLS 1.3, mTLS, RBAC, OAuth/JWT)
Переменные (Область видимости, встроенные, динамические)
Таймауты (виды, где\как применять, принцип работы)
Kubernetes-интеграция (gateway, ingress, service mesh)
Архитектура
HAProxy. Высокопроизводительный L4/L7-прокси с моделью master–worker и неблокирующим event-loop. Мастер руководит процессами, воркеры обрабатывают трафик — как шеф-повар, который не трогает еду, но следит, чтобы повара не спали. Поддерживает TCP/HTTP, TLS-терминацию, health-checks и продвинутые алгоритмы балансировки. Конфигурация статична, но есть Runtime API для живых правок; полный reconfigure делается через бесшовный reload. Типовой кейс: frontend
принимает HTTPS, терминирует TLS, выбирает backend
по leastconn
и отправляет запрос — pipeline прозрачнее, чем бюджет в стартапе.

NGINX. Архитектура «master + workers». Воркеры принимают TLS/HTTP, парсят протокол, применяют фильтры, кеш и проксируют на upstream
. Хорошо подходит для статических и программируемых конфигураций, если «динамика» нужна только на уровне переменных и Lua. Перезагрузка конфигурации обычно бесшовная: старые воркеры завершают запросы, новые уже готовы — никакой драмы, кроме как у админа в 3 ночи. Типовой кейс: server
с proxy_pass
на пул API, с кешем и ограничениями скорости по ключу. JWT/OAuth? Или Plus, или Lua — выбирайте, что меньше ломает мозг.

Envoy. Динамический L4/L7-прокси с фильтровой архитектурой и управлением через xDS. Конфигурация подтягивается из контрольной плоскости в реальном времени, маршрутизация гибкая до абсурда: можно отправить трафик хоть на кофемашину, если она объявилась в EDS. Поддерживает HTTP/1.1, HTTP/2, HTTP/3, gRPC, ретраи, метрики и обновляется через hot-restart без обрыва сокетов — хоть разворачивайся каждую минуту. Типовой кейс: listener с TLS, далее цепочка фильтров (ALPN → HTTP/2 → router) маршрутизирует gRPC-потоки по кластерам, которые сами приходят и уходят, как разработчики после демо.

Итого по архитектуре:
HAProxy — минимализм, высокая производительность, минимум магии.
NGINX — стабильность и зрелая экосистема, но с ограниченной гибкостью.
Envoy — динамика и API-центричность, но сложнее в эксплуатации.
Поддерживаемые протоколы

HAProxy работает как TCP/UDP-прокси и полнофункциональный HTTP-прокси. Поддерживает HTTP/1.1, HTTP/2 и HTTP/3 (QUIC
), включая ALPN (Application-Layer Protocol Negotiation
) и SNI (Server Name Indication
). Может терминировать TLS или проксировать TLS passthrough. gRPC работает в режиме HTTP/2 без сторонних плагинов.
frontend fe
mode http
bind :80
bind :443 ssl crt /etc/haproxy/certs/foo.com/cert.crt alpn h2
bind quic4@:443 ssl crt /mycert.pem alpn h3
http-request redirect scheme https unless { ssl_fc }
http-after-response add-header alt-svc 'h3=":443"; ma=60'
backend be_api
mode http
option httpchk GET /health
server s1 10.0.0.31:443 ssl verify none sni str(api.example.com) alpn h2 check
server s2 10.0.0.32:443 ssl verify none sni str(api.example.com) alpn h2 check
Входящий TLS-трафик принимается на порту 443, ALPN выбирает HTTP/2 или HTTP/3, затем HAProxy терминирует соединение, балансирует по серверам с поддержкой h2 и шифрует трафик заново. Плюсы: высокая производительность на L4 и L7, зрелая поддержка HTTP/2. Минусы: настройка HTTP/3/QUIC требует проверки и ручной конфигурации; для сложных L7-правил доступны только ACL и Lua. Downstream/Upstream: HAProxy может принимать HTTP/1.1, HTTP/2 или HTTP/3 от клиентов (downstream) и независимо использовать любой протокол при подключении к бэкенду (upstream). Возможны сценарии h1→h2, h2→h1, h2→h2, h3→h1 и т.д., что позволяет менять протокол между клиентом и сервером без ограничений.
NGINX работает как TCP-stream прокси и как HTTP-прокси. Поддерживает HTTP/1.1 и HTTP/2 из коробки. HTTP/3/QUIC доступен с версии 1.25+ через директивы quic
и http3
. gRPC поддерживается через отдельный модуль grpc_pass
, который работает поверх HTTP/2.
server {
listen 443 ssl http2;
ssl_certificate /etc/nginx/certs/site.pem;
ssl_certificate_key /etc/nginx/certs/site.key;
location / {
proxy_pass https://backend_pool;
proxy_http_version 1.1;
}
}
server {
listen 8443 quic reuseport;
listen 8443 ssl;
ssl_certificate /etc/nginx/certs/site.pem;
ssl_certificate_key /etc/nginx/certs/site.key;
location /api {
add_header Alt-Svc 'h3=":8443"; ma=86400';
proxy_pass https://backend_pool;
proxy_http_version 1.1;
}
}
upstream backend_pool {
least_conn;
server 10.0.0.31:443;
server 10.0.0.32:443;
}
NGINX принимает TLS-соединения и включает HTTP/2 или HTTP/3 для клиентов, но к backend всё равно ходит по HTTP/1.1 (кроме gRPC). Плюсы: стабильный HTTP/2, простой конфиг. Минусы: HTTP/3 менее зрелый и требует ручного включения; stream-режим TCP не даёт детальной L7-логики; расширенные функции доступны только в Plus-версии. Downstream/Upstream: клиенты могут подключаться по HTTP/1.1, HTTP/2 или HTTP/3, но к backend соединение будет по HTTP/1.1 (кроме gRPC-location).
Envoy изначально построен как L4/L7-прокси с поддержкой TCP/UDP HTTP/1.1, HTTP/2, HTTP/3 и gRPC. Протоколы выбираются автоматически через ALPN, а фильтры позволяют обрабатывать как TCP, так и полный HTTP-поток. Для upstream на TLS/443 необходимо включить http2_protocol_options
и настроить transport_socket
для TLS.
Как примерно выглядит конфиг с поддержкой h1/h2/h3
admin:
address:
socket_address:
address: 127.0.0.1
port_value: 9901
static_resources:
listeners:
- name: main_listener
address:
socket_address:
address: 0.0.0.0
port_value: 443
# TLS конфигурация для HTTPS
listener_filters:
- name: envoy.filters.listener.tls_inspector
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
filter_chains:
- filter_chain_match:
application_protocols: ["h2", "http/1.1"]
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsConfig
common_tls_context:
tls_certificates:
- certificate_chain: {filename: "/etc/envoy/cert.pem"}
private_key: {filename: "/etc/envoy/privkey.pem"}
require_client_certificate: false
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
http2_protocol_options: {}
http_protocol_options: {}
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: {prefix: "/"}
route: {cluster: backend_cluster}
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
# Отдельный filter chain для HTTP/3
- filter_chain_match:
transport_protocol: "quic"
transport_socket:
name: envoy.transport_sockets.quic
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicDownstreamTransportConfig
downstream_tls_context:
common_tls_context:
tls_certificates:
- certificate_chain: {filename: "/etc/envoy/cert.pem"}
private_key: {filename: "/etc/envoy/privkey.pem"}
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http_quic
http2_protocol_options: {}
http_protocol_options: {}
codec_type: HTTP3
route_config:
name: local_route_quic
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: {prefix: "/"}
route: {cluster: backend_cluster}
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
# UDP listener для QUIC
udp_listener_config:
quic_options: {}
clusters:
- name: backend_cluster
connect_timeout: 5s
type: STATIC
lb_policy: ROUND_ROBIN
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: backend_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8080
Envoy listener принимает соединения на 443, сам определяет протокол (h1/h2/h3), маршрутизирует поток на пул с тем же протоколом или переводит его в нужный режим. gRPC обрабатывается нативно через HTTP/2. Плюсы: полная поддержка современных протоколов, гибкость через фильтры, без перезапуска можно менять маршруты. Минусы: выше потребление ресурсов, сложнее конфигурация для простых TCP-сценариев. Downstream/Upstream: Envoy автоматически конвертирует любые протоколы — h1↔h2↔h3 в любых комбинациях. Можно принимать h3 downstream и ходить к бэкенду по h1, или наоборот.
HAProxy — чемпион по скорости, будто с допингом. Глотает TCP, HTTP/1.1, HTTP/2, HTTP/3 и даже gRPC без костылей. Протокол downstream/upstream можно миксовать как коктейли на корпоративе — хоть h3→h1, хоть h1→h2. Минус: для QUIC придётся повозиться с ручной настройкой, а за сложные L7-правила — только ACL и Lua, никакой встроенной магии. Но зато latency минимальная, как у хорошего эспрессо.
NGINX — надёжен как дедовский жигуль: HTTP/2 держит стабильно, HTTP/3 прикручен «на синюю изоленту», а сложной L7-логики не жди. TCP через stream идёт, но апгрейд backend до h2 не завезут — хочешь комфорта, смотри NGINX Plus.
Envoy — как инженер с немецким дипломом: жонглирует h1/h2/h3 фильтрами, не потея и не перезапускаясь. Downstream хоть HTTP/3, backend хоть HTTP/1.1 — всё под контролем. Но ресурсы ест как браузер с сотней вкладок и требует знаний на уровне DevOps-соревнований.
Вывод:
HAProxy — брать, если нужна минимальная задержка и зрелый HTTP/1/2 без плясок.
NGINX — выбрать для стабильного HTTP/1/2 и простого конфига, но помнить про слабый upstream-функционал.
Envoy — король gRPC и любых протокольных миксов, но для банального L4-прокси это как на Porsche картошку возить.
Балансировка и маршрутизация

HAProxy поддерживает алгоритмы балансировки: roundrobin
, leastconn
, source
, uri
, hdr
, consistent-hash
. Маршрутизация уровня L7 реализуется через ACL: можно матчить по URI, заголовкам, TLS-отпечаткам (JA3/JA4) с использованием Lua.
frontend fe_api
bind :443 ssl crt /etc/haproxy/certs/api.pem
acl v1 path_beg /v1/
use_backend be_v1 if v1
default_backend be_v2
backend be_v1
balance leastconn
server s1 10.0.0.41:443 ssl verify none check
server s2 10.0.0.42:443 ssl verify none check
backend be_v2
balance uri
hash-type consistent
server s3 10.0.0.43:443 ssl verify none check
server s4 10.0.0.44:443 ssl verify none check
Фронтенд принимает HTTPS-запросы, проверяет путь /v1/
и отправляет их в пул be_v1
с балансировкой по наименьшему числу активных подключений. Остальные запросы попадают в пул be_v2
с консистентным хешированием URI.
NGINX поддерживаемые алгоритмы: round_robin
(по умолчанию), least_conn
, ip_hash
, hash
с опцией consistent
. Маршруты уровня L7 задаются через location
. Конфигурация обновляется только через reload.
upstream api_v1 {
least_conn;
server api1.local:443;
server api2.local:443;
}
upstream api_v2 {
hash $request_uri consistent;
server api3.local:443;
server api4.local:443;
}
server {
listen 443 ssl http2;
ssl_certificate /etc/nginx/certs/api.pem;
ssl_certificate_key /etc/nginx/certs/api.key;
proxy_ssl_server_name on;
location /v1/ { proxy_pass https://api_v1; }
location / { proxy_pass https://api_v2; }
}
Запросы к /v1/
перенаправляются на пул api_v1
с алгоритмом least_conn
. Остальные — на api_v2
с консистентным хешированием URI.
Envoy поддерживает алгоритмы: round_robin
, least_request
, maglev
, ring_hash
, а также веса, канареечные релизы, shadow-трафик. Управление и маршрутизация меняются динамически через xDS.
static_resources:
listeners:
- name: https_listener
address: { socket_address: { address: 0.0.0.0, port_value: 443 } }
filter_chains:
- transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain: { filename: "/etc/envoy/tls/api.crt" }
private_key: { filename: "/etc/envoy/tls/api.key" }
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress
route_config:
virtual_hosts:
- name: api
domains: ["*"]
routes:
- match: { prefix: "/v1/" }
route: { cluster: api_v1 }
- match: { prefix: "/" }
route: { cluster: api_v2 }
http_filters:
- name: envoy.filters.http.router
clusters:
- name: api_v1
lb_policy: LEAST_REQUEST
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: "api.internal"
load_assignment:
cluster_name: api_v1
endpoints:
- lb_endpoints:
- endpoint: { address: { socket_address: { address: api1.local, port_value: 443 }}}
- name: api_v2
lb_policy: MAGLEV
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: "api.internal"
load_assignment:
cluster_name: api_v2
endpoints:
- lb_endpoints:
- endpoint: { address: { socket_address: { address: api3.local, port_value: 443 }}}
Envoy слушает HTTPS-трафик на порту 443, маршрутизирует запросы по префиксу URI: /v1/
→ кластер api_v1
(least_request), /
→ кластер api_v2
(Maglev). Все соединения к апстримам идут по TLS с проверкой SNI.
HAProxy — работает как швейцарский механизм: поддерживает roundrobin
, leastconn
, source
, uri
, hdr
, consistent-hash
— всё стабильно и предсказуемо. L7-маршруты через ACL: можно матчить по URI
, заголовкам, даже по TLS-отпечаткам (JA3/JA4). Конфигурация статична, но понятна и прозрачна.
NGINX — минимализм без сюрпризов: доступны только round_robin
, least_conn
, ip_hash
. HTTP-маршруты задаются через location
, но без динамических алгоритмов или ring_hash
. Sticky-сессии — только через ip_hash
, API для внешнего управления нет, расширенные возможности балансировки есть только в NGINX Plus. Хорош, если конфиг «разложил и забыл», а трафик стабилен.
Envoy — тяжёлая артиллерия: поддерживает round_robin
, least_request
, maglev
, ring_hash
, веса, канареечные релизы, shadow-трафик. Всё управляется динамически через xDS — можно менять маршруты хоть каждую секунду. Но YAML-схемы перегружены и требуют опыта, иначе будет больно. Для сложной продакшен-динамики — это лучший выбор, но придётся вложиться в автоматизацию и обучение.
Выводы:
HAProxy — низкая задержка и предсказуемый контроль L4/L7. Настроил ACL — и работает.
NGINX — статические маршруты без динамических требований. Конфиг «разложил и забыл».
Envoy — динамическое управление, канареечные релизы и сложные политики, но конфигурация громоздкая и требует автоматизации.
Надежность и отказоустойчивость

HAProxy обеспечивает встроенные механизмы отказоустойчивости на L4 и L7: активные health-check, повторные попытки при ошибках, circuit breaker через лимиты соединений, а также защиту от перегрузки через stick-tables.
global
maxconn 20000 # верхний предел соединений на процесс HAProxy
defaults
maxconn 10000 # лимит для фронтендов/бэкендов по умолчанию
backend be_api
mode http
option httpchk GET /health
retry-on all-retryable-errors
retries 3
http-request disable-l7-retry if METH_POST METH_PUT METH_DELETE
default-server inter 2s fall 3 rise 2
server s1 10.0.0.51:443 ssl verify none maxconn 500
server s2 10.0.0.52:443 ssl verify none maxconn 500
stick-table type ip size 1m expire 10m store conn_rate(10s)
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_conn_rate gt 100 }
Серверы проверяются каждые две секунды по пути /health. Они исключаются из пула после трёх неудачных ответов и возвращаются обратно после двух успешных. Если лимит подключений к серверу (500 соединений) превышен, лишние запросы становятся в очередь и ожидают timeout queue
(по умолчанию — от timeout connect
), после чего возвращается 503. Параметр retries 3
выполняет до трёх попыток соединения (исходная + до двух повторов), а опция retry-on all-retryable-errors
и директива http-request disable-l7-retry
гарантируют, что HAProxy будет повторять только идемпотентные методы и не будет ретраить POST, PUT, DELETE. Параметры global maxconn
и server maxconn
задают верхние пределы соединений на процесс и на каждый backend. Практический предел зависит также от лимита файловых дескрипторов (ulimit -n
), поскольку одно проксируемое соединение обычно требует два FD(≈1–2 FD на сессию). Дополнительно stick-tables отслеживают частоту подключений и блокируют источник при превышении порога, например 100 соединений за 10 секунд.
NGINX использует пассивные health-check (max_fails
/fail_timeout
) и proxy_next_upstream
для fallback. Важно понимать нюанс подсчёта повторов: proxy_next_upstream_tries N
считается на всю upstream-группу, то есть при proxy_next_upstream_tries 3 реально получается исходный запрос + до 2 повторов по остальным серверам (итого 1 + 2), а не 1 + 3 для каждого backend.
worker_processes auto;
worker_rlimit_nofile 4096; # максимальное количество файловых дескрипторов, которые может использовать один worker-процесс
events {
worker_connections 2048; # максимальное число одновременных соединений, которые может обработать один worker-процесс
multi_accept on;
}
http {
upstream api_pool {
least_conn;
server 10.0.0.51 max_fails=3 fail_timeout=5s;
server 10.0.0.52 max_fails=3 fail_timeout=5s;
}
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=100r/s;
server {
listen 443 ssl;
limit_req zone=req_limit burst=50;
proxy_pass https://api_pool;
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_next_upstream_tries 3;
}
}
При трёх ошибках подряд сервер исключается из пула на пять секунд. Для ограничения нагрузки используются limit_req
и limit_conn
, которые регулируют частоту и количество запросов на клиента или глобально. Максимальное число соединений на процесс определяется как минимум из worker_connections
и worker_rlimit_nofile
, а реальный предел для всех воркеров равен произведению числа процессов на лимит воркера, с учётом того, что одно проксируемое соединение использует около двух файловых дескрипторов. В Open-Source NGINX нет per-backend лимитов, аналогичных server maxconn
; эти возможности (max_conns и очередь на апстриме) есть только в NGINX Plus.
Envoy предоставляет полный набор инструментов: активные health-check (HTTP/TCP/gRPC), circuit breaking с лимитами по соединениям, запросам и ошибкам, retries с гибкой политикой, outlier detection для автоматического исключения проблемных узлов и фильтры для ограничения входящих соединений
static_resources:
listeners:
- name: https_listener
address: { socket_address: { address: 0.0.0.0, port_value: 443 } }
filter_chains:
- filters:
- name: envoy.filters.network.connection_limit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit
stat_prefix: conn_limit
max_connections: 10000
delay: 0s
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress
route_config: { ... }
http_filters: [ { name: envoy.filters.http.router } ]
clusters:
- name: api_pool
lb_policy: LEAST_REQUEST
circuit_breakers:
thresholds:
- max_connections: 500
max_requests: 1000
health_checks:
- timeout: 1s
interval: 2s
unhealthy_threshold: 3
healthy_threshold: 2
http_health_check: { path: /health }
outlier_detection:
consecutive_5xx: 5
interval: 5s
base_ejection_time: 30s
Фильтр connection_limit
ограничивает входящие соединения на listener, а circuit breakers задают пределы подключений и одновременных запросов к каждому кластеру. Механизм retries настраивается в retry_policy
: параметр num_retries
определяет только повторные попытки, всего выполняется исходный запрос + num_retries
, а условия повтора можно задавать детально (например, только при отказе соединения или только при ответах 503) с использованием экспоненциального backoff. Количество файловых дескрипторов управляется на уровне ОС через ulimit -n
, а перегрузка отдельных серверов контролируется с помощью outlier detection, автоматически исключающего узлы с избыточными ошибками 5xx.
HAProxy — как строгий охранник у клуба: лишние соединения не пустит, пьяных клиентов выгонит (stick-tables), сердцебиение проверяет каждую секунду. Circuit breaker настраивается вручную, но работает чётко. Минус: сложные сценарии придётся писать на Lua или подключать внешнюю автоматику — без этого всё руками, как в старой школе DevOps.
NGINX — охранник без рации: может заметить, что клиент упал, но только если он реально свалился на пол. Активных health-check нет (оставили для платной версии), circuit breaker в зачатке. Зато лимиты соединений и запросов задаются парой директив, без магии и Lua. Хорош для стабильных пулов, где никто не бегает и свет не мигает.
Envoy — охранник с камерой, тепловизором и аналитикой на ИИ: активные проверки, circuit breaker на всё подряд, outlier detection, retries с умной задержкой. Встроенный или внешний rate limiting — на выбор. Минус: он просит больше зарплату (CPU/memory) и инструктаж посложнее, иначе случайно закроет дверь даже перед хозяином.
Вывод:
HAProxy — лучший выбор для L4/L7-балансировщиков, где нужна быстрая защита от перегрузки и детальная ручная настройка.
NGINX — подойдёт, если достаточно пассивных проверок и простых лимитов без динамики.
Envoy — подходит для живых систем с автоскейлом и централизованным контролем трафика, но требует аккуратного обращения.
Наблюдаемость

HAProxy выводит подробные логи через syslog (RFC5424/3164
), поддерживает structured logging (JSON) через log-format
и экспорт метрик в Prometheus через встроенный prometheus-exporter
или stats socket
. Встроенный веб-статус (stats uri
) есть, но распределённой трассировки нет — требуются внешние агенты (Jaeger, Zipkin).
global
log stdout format raw local0
stats socket /var/run/haproxy.sock mode 600 level admin
stats timeout 30s
defaults
log global
option httplog
log-format { "time":"%t", "frontend":"%f", "backend":"%b", "srv":"%s", "status":%ST, "bytes":%B }
frontend prometheus
bind *:8405
mode http
http-request use-service prometheus-exporter if { path /metrics }
no log
Логи пишутся в stdout, метрики публикуются по http://<host>:8405/metrics.
Плюсы: минимальные накладные расходы, детальные логи. Минусы: нет встроенной трассировки запросов, приходится интегрировать вручную.
NGINX поддерживает access/error
логи, может логировать в JSON для экспорта в ELK/Graylog. Метрики — только через сторонние модули (nginx-module-vts
, nginx-prometheus-exporter
). Встроенной распределённой трассировки нет (в отличие от NGINX Plus, где есть OpenTelemetry).
http {
log_format json_combined escape=json
'{ "time":"$time_iso8601",'
'"remote":"$remote_addr",'
'"host":"$host",'
'"request":"$request",'
'"status":$status,'
'"bytes":$body_bytes_sent }';
access_log /var/log/nginx/access.json json_combined;
server {
listen 80;
location / {
proxy_pass http://10.0.0.52:8080;
}
}
}
Трафик логируется в JSON, готов для парсинга внешними системами. Плюсы: гибкий формат логов, легко подключать ELK. Минусы: нет нативных метрик и трассировки, нужен внешний экспортер.
Envoy из коробки поддерживает structured logging, метрики в Prometheus, а также OpenTelemetry для распределённой трассировки (Jaeger, Zipkin, Datadog). Каждый фильтр может генерировать собственные статистики.
admin:
access_log_path: /dev/stdout
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
tracing:
http:
name: envoy.tracers.opentelemetry
typed_config:
"@type": type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig
grpc_service:
envoy_grpc:
cluster_name: otel_collector
Envoy пишет логи и метрики напрямую(http://<host>:9901/stats/prometheus
), трассировка передается в OpenTelemetry Collector. Плюсы: нативная поддержка Prometheus и трассировки, детализированные метрики L4/L7.
HAProxy — пишет логи быстро и честно, как будто ведёт дневник без цензуры. Легко отдаёт метрики Prometheus через экспортер, а встроенный веб-статус даёт картинку без лишних зависимостей. Но трассировку придётся прикручивать самому — Lua, агенты, шаманский бубен.
NGINX — логи делает удобоваримыми в JSON и сразу готовыми для ELK, но метрики и трассировка — только через сторонние модули или экспортеры. Конфигурация простая, но никакой нативной магии для L7-метрик или распределённого следа. То есть видно, кто зашёл, но не куда он потом пошёл.
Envoy — наблюдает за всем, как параноидальный сосед с биноклем на пенсии. Логи структурированы, метрики идут прямо в Prometheus, а OpenTelemetry встроен из коробки: можно смотреть трассировку запроса от клиента до базы без внешних костылей. Минус: съедает больше ресурсов и требует аккуратной настройки, иначе легко утонуть в собственных графиках.
Вывод:
HAProxy — лёгкий и быстрый, но наблюдаемость только базовая.
NGINX — нормальные логи, но за метрики и трассировку придётся платить сторонними модулями и временем.
Envoy — лидер для глубокой наблюдаемости и трассировки без костылей, если готовы мириться с его аппетитами.
Безопасность

HAProxy — поддерживает TLS 1.3 и mTLS прямо на фронтендах, с версии 2.5 умеет проверять JWT и OAuth2 без внешних сервисов (http_auth_bearer
, jwt_verify
, jwt_payload
), а для RBAC применяют ACL и переменные. Zero Trust-сценарии реализуемы через SPIFFE/SPIRE, но требуют дополнительного glue-кода для ротации ключей.
frontend https_in
bind :443 ssl crt /etc/haproxy/certs.pem ca-file /etc/haproxy/ca.pem verify required
http-request set-var(txn.jwt) http_auth_bearer
http-request set-var(txn.verified) var(txn.jwt),jwt_verify(alg=RS256,key=/etc/haproxy/jwks.json)
http-request deny if { var(txn.verified) -m int 0 }
http-request set-var(txn.role) var(txn.jwt),jwt_payload,query(role)
acl role_admin var(txn.role) -m str admin
http-request deny unless role_admin
default_backend web
Производительность высокая, функционал политик менее гибкий, чем в Envoy, но достаточно для edge-защиты. За подробностями можно глянуть здесь. В OSS нативного WAF нет. Обычно используют ModSecurity через SPOE-агент или выносят проверку во внешний сервис с правилами OWASP CRS. Это добавляет операционную сложность и накладные расходы.
NGINX — прост в эксплуатации, но без встроенной проверки JWT в OSS-версии. TLS 1.3 и mTLS поддерживаются через стандартный ssl-модуль. JWT, OIDC и сложные RBAC-сценарии реализуют через внешний авторизатор (чаще всего oauth2-proxy) с auth_request
или через Lua/OpenResty. Zero Trust возможен, но интеграция со SPIFFE/SPIRE полностью ручная
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_client_certificate /etc/nginx/ssl/ca.pem;
ssl_verify_client on;
location / {
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
proxy_set_header X-Auth-Request-User $upstream_http_x_auth_request_user;
proxy_set_header X-Auth-Request-Email $upstream_http_x_auth_request_email;
proxy_pass http://backend;
}
location = /oauth2/auth { internal; proxy_pass http://oauth2-proxy; }
location /oauth2/ { proxy_pass http://oauth2-proxy; }
}
Прост в эксплуатации, надёжен, но без внешнего авторизатора сложные политики реализовать трудно. В OSS встроенного WAF нет. Чаще всего применяют libmodsecurity + модуль ModSecurity-nginx с профилем OWASP CRS. Всё настраивается вручную, нужно следить за обновлением правил и тюнинговать под нагрузку.
Envoy — оптимален для Zero Trust. Поддерживает TLS 1.3, mTLS, динамическую загрузку сертификатов через SDS, встроенные фильтры JWT, RBAC и OAuth2. Интеграция со SPIFFE/SPIRE нативная, сертификаты обновляются автоматически. OAuth2/OIDC решают через внешний IdP совместно с jwt_authn или ext_authz
Очень большой конфиг (danger)
static_resources:
listeners:
- name: main_listener
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: service_cluster
http_filters:
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
example_provider:
issuer: https://example.com
audiences:
- api.example.com
remote_jwks:
http_uri:
uri: https://example.com/.well-known/jwks.json
cluster: jwks_cluster
timeout: 1s
cache_duration:
seconds: 300
- name: envoy.filters.http.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
rules:
policies:
"require-valid-jwt":
permissions:
- any: true
principals:
- metadata:
filter: envoy.filters.http.jwt_authn
path:
- key: example_provider
value:
string_match:
exact: verified
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: service_cluster
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8081
- name: jwks_cluster
connect_timeout: 5s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: jwks_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: example.com
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: example.com
JWT проверяется через jwt_authn filter с поддержкой локальных и удалённых JWKS, а RBAC-фильтр позволяет описывать allow/deny-политику прямо в конфигурации. WAF: встроенного решения нет. Используют WASM-фильтры на базе Coraza (правила совместимы с OWASP CRS) или интегрируют Curiefense как Envoy-фильтр. Подход открытый, но требует тестов под прод-нагрузкой и ручной настройки правил.
HAProxy — шифрует быстро, JWT/OAuth2 проверяет нативно с версии 2.5 без лишних зависимостей. TLS 1.3 и mTLS на фронтендах, ACL и переменные для RBAC. Zero Trust через SPIFFE/SPIRE возможен, но придётся дописывать собственный «клей» для ротации ключей и распределения SVID. Хорош, когда важны скорость и простые политики без лишней магии.
NGINX — настраивается так же легко, как добавить новый upstream. TLS 1.3 и mTLS встроены, но JWT и OIDC в OSS нет — всё решается через внешний авторизатор (чаще oauth2-proxy). Сложный RBAC потребует вынесенной логики. Zero Trust сценарии возможны, но интеграция полностью ручная. Конфиг прост, но возможностей меньше, чем у HAProxy и Envoy.
Envoy — Zero Trust в чистом виде. TLS 1.3, mTLS, SDS для динамики ключей, встроенные фильтры JWT, RBAC, OAuth2. SPIFFE/SPIRE подключается нативно, сертификаты обновляются сами. Можно строить политику хоть под микроскопом, без лишних костылей.
Вывод:
HAProxy — быстрый минимализм: простые ACL и встроенная JWT/OAuth2-проверка.
NGINX — надёжен и понятен, но для сложных политик нужны внешние сервисы.
Envoy — всё для Zero Trust из коробки: TLS, mTLS, JWT, RBAC, OAuth2, SDS и SPIFFE.
Переменные
HAProxy — переменные бывают как коты в коробке Шрёдингера: живут то в транзакции (txn.*
), то в сессии (sess.*
), то в запросе (req.*
) или ответе (res.*
). Можно хранить что угодно: IP, токены, промежуточные флаги. Эти переменные легко помещать в ACL, логи или Lua.
frontend fe_https
bind :443 ssl crt /etc/haproxy/certs/site.pem alpn h2,http/1.1
mode http
http-request set-var(txn.client_ip) src
http-request set-header X-Client-IP %[var(txn.client_ip)]
default_backend be_api
backend be_api
mode http
http-request set-var(sess.backend_name) be_api
server s1 10.0.0.31:443 ssl verify none
server s2 10.0.0.32:443 ssl verify none
Здесь IP клиента записывается в переменную транзакции и сразу же уезжает в заголовок. Переменная sess.backend_name
живёт дольше — пока TCP-сессия не умрёт. Плюсы: быстрые ACL, всё можно хранить прямо в прокси. Минусы: сложные сценарии часто требуют Lua — готовься писать код прямо в конфиге, как в 2000-х.
NGINX — переменные как студенты на паре: появляются только на время запроса, потом испаряются. Есть встроенные ($host
, $remote_addr
) и те, что задаёшь руками через set
. Между запросами память не держат — хочешь что-то протащить дальше, прокидывай заголовки или ставь cookie.
server {
listen 443 ssl http2;
ssl_certificate /etc/nginx/certs/site.pem;
ssl_certificate_key /etc/nginx/certs/site.key;
set $client_ip $remote_addr;
location / {
proxy_set_header X-Client-IP $client_ip;
proxy_pass https://backend_pool;
}
}
upstream backend_pool {
least_conn;
server 10.0.0.31:443;
server 10.0.0.32:443;
}
Переменная $client_ip
живёт ровно один запрос, как батарейка в китайском фонарике. Плюсы: просто, стабильно, никаких утечек состояния. Минусы: никакой «долгой памяти», всё руками через заголовки.
Envoy — вместо переменных тут подстановки и метаданные. %DOWNSTREAM_REMOTE_ADDRESS%
, %REQ(:authority)%
, %UPSTREAM_HOST%
и десятки других. Можно хранить временные данные прямо внутри фильтров — хочешь память на уровень TCP, хочешь на уровень HTTP-запроса.
static_resources:
listeners:
- name: https_listener
address:
socket_address: { address: 0.0.0.0, port_value: 443 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress
route_config:
virtual_hosts:
- name: api
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: api_pool
request_headers_to_add:
- header:
key: X-Client-IP
value: "%DOWNSTREAM_REMOTE_ADDRESS%"
http_filters:
- name: envoy.filters.http.router
Envoy сам добавляет X-Client-IP
из встроенной подстановки. А если захочешь хранить ещё что-то — используй Dynamic Metadata, и у тебя будет «карманная база данных внутри прокси». Плюсы: гибкость и фильтры как LEGO. Минусы: сложность конфига, настраивать без кофе опасно.
Вывод:
HAProxy — переменные на любой вкус и срок жизни, но Lua придётся учить.
NGINX — переменные как одноразовые стаканчики: удобно, но без повторного использования.
Envoy — это как владение магией: невероятная мощь, но один неверный символ в метаданных или переменной и ты уже не повелеваешь трафиком, а тушишь фаервол.
Таймауты

HAProxy таймаутов столько, что можно потеряться. Таймауты обычно указывают в секциях defaults
/frontend
/backend
. Главные параметры: timeout connect
(тайм-аут на установку TCP), timeout client
(неактивность со стороны клиента), timeout server
(неактивность со стороны бэкенда), timeout http-request
(время ожидания заголовков запроса), timeout http-keep-alive
и timeout tunnel
для туннелей/вебсокетов. Таймауты часто задаются явно в defaults
; без корректных значений соединения могут «залипать» или падать. Каждый отвечает за свой этап: соединение, запрос, очередь, туннель. Можно гибко настроить поведение и на L4, и на L7.
defaults
timeout connect 5s
timeout client 1m
timeout server 1m
timeout http-request 10s
timeout queue 15s
timeout http-keep-alive 15s
timeout tunnel 1h
Соединение к backend ждём 5 секунд, клиентский запрос и ответ сервера — по 1 минуте, запросы на уровне HTTP проверяем 10 секунд, очередь не держим дольше 15 секунд. Плюсы: полный контроль, можно «настроить до болтика». Минусы: легко запутаться, если лепить всё подряд, конфиг превращается в «таймаутное болото».
NGINX даёт набор директив для клиента и прокси. Ключевые: client_header_timeout
, client_body_timeout
— время чтения заголовков/тела от клиента; keepalive_timeout
— время удержания keep-alive; proxy_connect_timeout
, proxy_read_timeout
, proxy_send_timeout
— поведение при proxy_pass: подключение, чтение ответа и отправка запроса учитываются между последовательными операциями, а не за весь ответ. То есть proxy_read_timeout
измеряет паузу между чтениями, а не общий срок передачи.
http {
client_header_timeout 60s;
client_body_timeout 60s;
keepalive_timeout 75s;
proxy_connect_timeout 10s;
proxy_read_timeout 300s; # увеличить для долгих ответов/streaming
proxy_send_timeout 300s;
}
Для потоковых gRPC/HTTP2 соединений нужно поднять proxy_*_timeout
и следить за http2_recv_timeout
/настройками upstream. Минусы: меньше гранулярности, чем у HAProxy, например, нет отдельного таймаута очереди или туннеля — всё «оптом».
Envoy оперирует таймаутами на уровне connection manager, route и cluster. Важные пункты: route timeout
по умолчанию 15s (это время ожидания полного upstream-ответа; стартует после получения всего downstream-запроса), stream_idle_timeout
у HTTP connection manager по умолчанию 5 минут (закрывает бездействующие стримы), cluster.connect_timeout
/transport_socket_connect_timeout
по умолчанию ~5s. Таймауты можно задавать глобально и на уровне маршрута; per-route timeout: 0s
отключает таймаут маршрута. Для стриминговых API нужно отключать/увеличивать route/stream таймауты.
http_connection_manager:
stream_idle_timeout: 300s # обычно 5m по умолчанию
route_config:
virtual_hosts:
- name: default
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: service_a
timeout: 0s # отключить route timeout для стриминга
idle_timeout: 0s # отключить per-route idle
В Envoy поведение таймаутов сложнее из-за retry/retry-timeout и взаимодействия connection-manager ↔ route ↔ cluster. Тестируйте сценарии с retry и streaming. Плюсы: гибкость, можно делать очень тонкие сценарии. Минусы: конфиг превращается в «головоломку на скорость», без документации самому себе — через неделю не разберёшься.
HAProxy — с таймаутами как со швейцарскими часами. Всё задаётся явно: connect, client, server, http-request, keep-alive, tunnel. Хочешь стриминг — поставь timeout tunnel и забудь. Минимум магии, максимум контроля. Если соединение зависло — это твоя вина, а не сюрприз в дефолтах.
NGINX — таймауты как бытовая техника. Client, proxy, keepalive — всё просто и понятно, но надо помнить, что proxy_read_timeout
меряет паузы между байтами, а не всю загрузку. Для долгих gRPC или стриминга таймауты придётся крутить руками. Работает надёжно, если не забыть про все ручки.
Envoy — таймауты как корпоративные дедлайны. По умолчанию route timeout
15 секунд, stream_idle_timeout
5 минут — и Envoy безжалостно разрывает стриминг, если не объяснить, что проект ещё не готов. Гибкости море: можно отключить таймауты, настроить idle отдельно на route и cluster, но придётся думать, что именно отключать.
Вывод:
HAProxy — максимальная детализация: можно настроить всё, даже «таймаут на таймаут». Но легко перестараться.
NGINX — базовый набор: быстро, понятно, но без редких «спецрежимов».
Envoy — конструктор с любыми таймаутами на любой уровень, но нужно помнить, что гибкость требует мозгов и кофе.
Kubernetes-интеграция

HAProxy. Есть два OSS-варианта:
haproxytech/kubernetes-ingress — классический Ingress с аннотациями, поддержка Gateway API флагом. Метрики для Prometheus из коробки. Плавная миграция на новые API.
jcmoraisjr/haproxy-ingress — тоже Ingress v1, частичная поддержка Gateway API (HTTPRoute/Gateway в v0.14). Подойдёт, если ближе его модель конфигурации.
Минимум магии, максимум контроля. Если что-то не работает — виноваты не «умные дефолты», а конкретные настройки.
NGINX Ingress Controller — фокус на Ingress v1. TLS/mTLS через аннотации (auth-tls-*
), внешняя авторизация (auth-url
), глобальные параметры через ConfigMap. Всё просто, но за сложные сценарии придётся платить количеством аннотаций. Работает стабильно, но «особые режимы» придётся включать руками.
Envoy Gateway (OSS) — нативный Gateway API, расширения SecurityPolicy для mTLS/JWT и авторизации по клеймам, метрики Prometheus.
Contour — управляет Envoy, поддерживает Gateway API и свои CRD для HTTP/gRPC/TCP. Гибкости море: route, cluster, policy — всё настраивается. Но за каждую опцию придётся думать.
Istio — mesh как отдельный отдел. Envoy выполняет роль data plane, политика и телеметрия централизуются через контроль-плейн. Если mesh уже есть или планируется — Ingress лучше строить на Istio или Gateway API с Envoy Gateway, чтобы не плодить зоопарк контроллеров.
Кратко:
Хотите «всё под контролем» и минимум сюрпризов — HAProxy.
Хотите «просто работает» — NGINX.
Хотите «тонкая политика и современные API» — Envoy Gateway или Contour.
Хотите «единая политика на весь трафик» — Istio.
Вывод
HAProxy — максимальная детализация, можно настроить всё. Но легко утонуть в параметрах.
NGINX — базовый и понятный путь. Быстро стартовать, без редких «сюрпризов».
Envoy/Contour — гибкость и глубокая интеграция с Gateway API. Требует продуманной конфигурации.
Istio — если mesh уже в планах, Ingress лучше сразу строить на нём.
Выводы и рекомендации

Подойдёт, когда важна минимальная латентность, высокая пропускная способность и предсказуемое поведение без control-plane. Нативная сильная сторона — L4/L7 балансировка с детальной ручной настройкой (таймауты, maxconn, stick-tables, httpchk). QUIC/H3 в активной доработке — уже можно тестировать, но планируйте нагрузочные тесты.
Когда брать:
Edge TLS-терминация с высокими SLA по latency.
Большие объёмы TCP/HTTP трафика, где нужна малая задержка.
Нужен контроль на уровне соединений и простая схема автозамены бэкендов (seamless reload).
Операционные ограничения и подводные камни:
Сложные L7-политики требуют Lua или внешней логики.
HTTP/3 требует тестов и знаний о QUIC.
Нет встроенной «из коробки» распределённой трассировки — нужно подключать OTEL/агрегаторы.

Лучше для простых и стабильных веб-фронтов, кэширования и ситуаций, где конфиг «разложил и забыл». HTTP/2 зрел, HTTP/3 стабилизируется в mainline. Для WAF/JWT/metrics/tracing — внешние модули или Plus
Когда брать:
Статический контент, reverse-proxy с кешем, rate-limiting на уровне edge.
Быстрый rollout и простая конфигурация без control-plane.
Нужен модульный моддинг (lua, njs) для лёгкого расширения.
Операционные ограничения и подводные камни:
Активные health-checks, advanced LB и enterprise-функции в основном в Plus.
Метрики и трассировка требуют внешних экспортеров/модулей.

Если система динамическая, микросервисная, с gRPC, канареечными релизами, shadow-трафиком и требованием к глубокой телеметрии — Envoy даёт наилучшую платформу. Требует control-plane (xDS) и автоматизации.
Когда брать:
Service mesh или централизованное управление L7-политиками.
gRPC-first архитектуры и обширная трассировка/OTel.
Нужно гибкое управление канареями, retry/circuit-breaker, rate-limit через внешние сервисы.
Операционные ограничения и подводные камни:
Высокая сложность конфигурации и поддержания YAML-политик.
Больше CPU/RAM на экземплах по сравнению с NGINX/HAProxy.
Требует CI/CD для xDS/контроль-плейна и хорошей наблюдаемости.
Итого по синтетическому разбору:
Низкая латентность и грубая производительность L4/L7 → HAProxy
Простой веб-фронт, кеш, статический контент, минимум динамики → NGINX
Динамичная среда, gRPC, mesh, канареи/трафик-менеджмент → Envoy
Практические советы по внедрению
Test-first: для HTTP/3 и QUIC задействуйте этап нагрузочного теста и SLO-валидацию
Observability: если выбираете Envoy — проектируйте OTEL-пайплайн сразу. Для HAProxy/NGINX готовьте Prometheus → OTEL/Jaeger интеграцию
K8s: для простого ingress — ingress-nginx или haproxy-ingress; для политики и mesh — Envoy Gateway/Contour/Istio. Планируйте единый control-plane, чтобы не плодить контроллеров.
Ресурсы: закладывайте больше CPU/RAM под Envoy и автоматизацию для его конфигураций.
NGINX — как велосипед с корзинкой: завёл и забыл, но далеко не уедешь. HAProxy — как надёжный жигуль: предсказуемо, стабильно, но без наворотов. Envoy — как BMW: летит быстро и уверенно, но вечно приходится ковыряться под капотом. Всё едет, вопрос только — куда и с какой скоростью.
Кто победил?
По сумме плюсов — Envoy, остаётся лучшим выбором для динамических, telemetry-heavy и gRPC-проектов. HAProxy держит первенство по сырой производительности и простоте L4/L7 в высоких нагрузках. NGINX остаётся лучшим выбором для традиционных web/edge сценариев с простым управлением и кешированием.
P.S. Если я в процессе написания статьи где-то что-то упустил, ошибся в конфиге или описании — присылайте исправления в личку, чтобы я мог внести их в статью.