Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
14 KiB
Руководство по High-Load конфигурации и тюнингу
При развертывании Telemt под высокой нагрузкой (десятки и сотни тысяч одновременных подключений), стандартные ограничения сетевого стека ОС могут приводить к потерям пакетов, переключениям контекста CPU и отказам в соединениях. В данном руководстве описана настройка ядра Linux, системных лимитов и аппаратной конфигурации для работы в подобных сценариях.
1. Системные лимиты и файловые дескрипторы
Каждое TCP-сосоединение требует файлового дескриптора. При 100 тысячах соединений стандартные лимиты Linux (зачастую 1024 или 65535) будут исчерпаны немедленно.
Общесистемные лимиты (sysctl)
Увеличьте глобальный лимит файловых дескрипторов в /etc/sysctl.conf:
fs.file-max = 2097152
fs.nr_open = 2097152
На уровне пользователя (limits.conf)
Отредактируйте /etc/security/limits.conf, чтобы разрешить пользователю (от которого запущен telemt) резервировать дескрипторы:
* soft nofile 1048576
* hard nofile 1048576
root soft nofile 1048576
root hard nofile 1048576
Переопределения для Systemd / Docker
Если используется Systemd, добавьте в ваш telemt.service:
[Service]
LimitNOFILE=1048576
LimitNPROC=65535
TasksMax=infinity
Если используется Docker, задайте ulimits в docker-compose.yaml:
services:
telemt:
ulimits:
nofile:
soft: 1048576
hard: 1048576
2. Тонкая настройка сетевого стека ядра (sysctl)
Создайте выделенный файл /etc/sysctl.d/99-telemt-highload.conf и примените его через sysctl -p /etc/sysctl.d/99-telemt-highload.conf.
2.1 Очереди соединений и защита от SYN-флуда
Увеличьте размеры очередей, чтобы поглощать внезапные всплески соединений и смягчить атаки типа SYN flood:
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1
2.2 Исчерпание портов и TIME-WAIT сокеты
Высокая текучесть приводит к нехватке временных (ephemeral) портов. Расширьте диапазон портов и позвольте ядру быстро переиспользовать закрытые сокеты:
net.ipv4.ip_local_port_range = 10000 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 2000000
2.3 TCP Keepalive (Агрессивная очистка мертвых соединений)
По умолчанию Linux держит "оборванные" TCP-сессии более 2 часов. Значения ниже начинают probes после пяти минут простоя и закрывают не отвечающий peer после последующего probe budget — примерно через 7–8 минут общего простоя:
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
2.4 Буферы TCP и управление перегрузками (Congestion Control)
Оптимизируйте использование памяти на сокет и переключитесь на алгоритм BBR (Bottleneck Bandwidth and Round-trip propagation time) для улучшения задержки на плохих сетях:
# Core buffer sizes
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# TCP-specific buffers (min, default, max)
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Enable BBR
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
3. Тюнинг Conntrack (Netfilter)
Если ваш сервер использует iptables, ufw или firewalld, ядро вынуждено отслеживать каждое соединение в таблице состояний (nf_conntrack). Когда эта таблица переполняется, Linux отбрасывает новые пакеты без уведомления приложения.
Проверьте текущие лимиты и использование:
sysctl net.netfilter.nf_conntrack_max
sysctl net.netfilter.nf_conntrack_count
Если вы близки к пределу, увеличьте таблицу и заставьте ядро быстрее удалять установленные соединения. Добавьте в /etc/sysctl.d/99-telemt-highload.conf:
# In /etc/sysctl.d/99-telemt-highload.conf
net.netfilter.nf_conntrack_max = 2097152
# Reduce timeout from default 5 days to 1 hour
net.netfilter.nf_conntrack_tcp_timeout_established = 3600
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 12
Внимание: в зависимости от ОС, вам может потребоваться выполнить modprobe nf_conntrack перед установкой этих параметров.
Когда server.conntrack_control.inline_conntrack_control = true и [server.conntrack_control] использует notrack или hybrid, один generation-fenced authority владеет только правилами conntrack control, созданными Telemt. Он применяет изменения IPv4 и IPv6, игнорирует устаревшие или конфликтующие публикации и повторяет неудачный reconcile через 1, 2, 4, 8, 16 и далее не более чем 30 секунд. Частичный многошаговый сбой запускает best-effort восстановление; неудачный rollback оставляет applied firewall state неизвестным до следующего успешного reconcile. telemt_conntrack_control_state{flag="rule_apply_ok"} показывает, действует ли требуемый набор правил. При включённой core telemetry попытки используют telemt_conntrack_rule_reconcile_total{result="success"|"error"} и telemt_conntrack_rule_rollback_total{result="success"|"error"}. При shutdown выполняется ограниченный 30 секундами best-effort cleanup собственных правил. Настройки conntrack control требуют перезапуска.
4. Архитектура: развёртывание за HAProxy
4.1 L4-развёртывание native MTProxy и TLS-front
Для массового native MTProxy- или TLS-front-трафика L4 HAProxy может поглощать всплески соединений перед передачей TCP streams в Telemt. Следующий пример не подходит для WEB-listener.
Оптимизация haproxy.cfg для High-Load
global
# Disable detailed connection logs under load
log stdout format raw local0 err
maxconn 250000
# Tune buffers and socket acceptance
tune.bufsize 16384
tune.maxaccept 64
defaults
log global
mode tcp
option clitcpka
option srvtcpka
timeout connect 5s
timeout client 1h
timeout server 1h
# Purge dead peers quickly
timeout client-fin 10s
timeout server-fin 10s
frontend proxy_in
bind *:443
maxconn 250000
option tcp-smart-accept
default_backend telemt_backend
backend telemt_backend
option tcp-smart-connect
# Preserve the client IP for Telemt through PROXY v2
server telemt_core 10.10.10.1:443 maxconn 250000 send-proxy-v2 check inter 5s
Важно: Telemt должен быть настроен на обработку протокола PROXY на порту 443, чтобы получать оригинальные IP-адреса клиентов.
4.2 WEB-развёртывание
WEB-режиму требуется L7 TLS-терминатор и приватный plain HTTP/1.1 listener Telemt с proxy_protocol = false; не используйте для него L4 backend с send-proxy-v2 из предыдущего примера. Следуйте полному руководству по WEB-прокси, сохраняйте Host, точные path и query, WebSocket Upgrade headers и передавайте один перезаписанный X-Forwarded-For только от явно доверенных CIDR терминатора. Public ALPN должен предлагать h2 для https-lanes и http/1.1 для WebSocket Upgrade.
Для WEB-listener задайте web_client_ip_source = "x_forwarded_for" и укажите в web_trusted_proxy_cidrs только адреса непосредственного HAProxy. Не доверяйте доступной клиентам подсети и не включайте PROXY protocol на этом listener.
Направляйте весь vhost в один процесс Telemt. При совместном размещении по prefix сохраняйте настроенный base_path без rewrite; во время миграции направляйте в Telemt старое и новое поддеревья, пока ранее выпущенные процессом credentials ещё могут использоваться. Multi-process backend требует affinity всего vhost для bridge root, создания и восстановления session, uplink, downlink, DELETE, diagnostics и WebSocket Upgrade.
Например, следующий фрагмент HAProxy направляет только точный host и WEB-поддерево с завершающим слешем, не изменяя request target:
frontend https_in
mode http
bind *:443 ssl crt /etc/haproxy/certs/proxy.pem alpn h2,http/1.1
timeout client 65s
acl telemt_web_host hdr(host) -i proxy.example.com proxy.example.com:443
acl telemt_web_path path_beg /telegram/web/
use_backend telemt_web if telemt_web_host telemt_web_path
backend telemt_web
mode http
retries 0
timeout connect 5s
timeout server 65s
http-request set-header Host proxy.example.com
http-request set-header X-Forwarded-For %[src]
server telemt_web_1 127.0.0.1:18080 check
Обрабатывайте путь без завершающего слеша /telegram/web вне этого backend, чтобы frontend не создавал redirect alias в аутентифицированное поддерево. Не добавляйте set-path, replace-path или path-компонент к адресу backend server. Значения 65 секунд — пример для defaults; client и server timeouts должны быть больше web.timeouts.long_poll_secs и удвоенного effective WebSocket liveness interval.
При расчёте capacity учитывайте одновременно публичные TLS sockets и приватные sockets между терминатором и Telemt. Совместно рассчитывайте file descriptors, upstream capacity терминатора, web.limits.max_http_connections, handler capacity, параллельные long polls и WebSocket lanes; upstream keepalive pool не является лимитом concurrency.
5. Диагностика и мониторинг
- Переполнение listen queues: проверяйте
ListenOverflowsиListenDropsв/proc/net/netstatлибо черезnstat. - Conntrack pressure: проверяйте
nf_conntrack_count, kernel logs иtelemt_conntrack_control_state{flag="rule_apply_ok"}; при включённой core telemetry также проверяйте счётчики reconcile/rollback выше. - File descriptors:
cat /proc/sys/fs/file-nrи лимиты процесса Telemt в/proc/<pid>/limits. - Состояния соединений:
ss -s; избегайте полного сканирования черезnetstatна нагруженном сервере. - Rate limiter contention: при включённой core telemetry настройте alert на положительный прирост или rate counter, например
increase(telemt_rate_limiter_cas_retry_exhausted_total[5m]) > 0, с группировкой поscope,directionиoperation. Reserve exhaustion возвращает нулевой grant без классификации как настроенный throttle; refund exhaustion сохраняет списание. Эта метрика не является ни счётчиком dropped connections, ни счётчиком policy throttling. - WEB: объединяйте telemetry терминатора и внешний TLS probe с
/v1/runtime/web/status,telemt_web_tcp_accept_total{result="accepted"|"error"}и остальнымиtelemt_web_*metrics. Request path иbase_pathнамеренно не используются как metric labels.