Когда TCP-сервер начинает захлебываться под нагрузкой, проблема не всегда в CPU, памяти или плохом приложении. Иногда упирается сам механизм приема новых соединений. Чтобы понять, что происходит, полезно знать три вещи: SYN flood, backlog и somaxconn
▪️ Как выглядит обычное TCP-подключение:
клиент отправляет SYN
сервер отвечает SYN-ACK
клиент присылает ACK
соединение считается установленным
Но между "клиент постучался" и "приложение приняло соединение" есть очереди ядра.
▪️ Что может пойти не так:
SYN flood. Сервер получает огромное количество SYN, но рукопожатие не завершается. Это может быть атака, кривой балансировщик, сетевые потери или просто всплеск нагрузки. В итоге очередь полуоткрытых соединений заполняется, и новые клиенты начинают теряться.
backlog. Когда приложение вызывает listen(), оно указывает размер очереди ожидающих подключений.
Если приложение не успевает быстро принимать новые соединения через accept(), очередь переполняется.
Тогда часть клиентов начинает видеть: таймауты, connection refused, повторные SYN, странные задержки на подключении.
somaxconn. Это системный лимит ядра на максимальный backlog. Даже если приложение просит большую очередь, ядро все равно ограничит ее значением net.core.somaxconn.
Посмотреть можно так:
sysctl net.core.somaxconn
А заодно часто смотрят:
sysctl net.ipv4.tcp_max_syn_backlog
Первый параметр влияет на очередь установленных, но еще не принятых приложением соединений. Второй на очередь полуоткрытых SYN.
▪️ Что происходит на перегруженном сервере на практике:
приложение медленно вызывает accept()
очередь backlog заполняется
новые подключения начинают отваливаться
если сверху еще идет SYN flood, ситуация усугубляется
снаружи кажется, что сервер то работает, то нет
▪️ Как смотреть симптомы:
ss -lnt
netstat -s | grep -i listen
dmesg | grep -i syn
▪️ Что обычно помогает:
увеличить somaxconn;
проверить backlog самого приложения;
поднять tcp_max_syn_backlog;
включить или проверить SYN cookies;
разбираться, почему приложение медленно принимает соединения;
выносить защиту от flood на firewall/LB;
Например:
sysctl -w net.core.somaxconn=4096
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
Но увеличение очередей не лечит корень проблемы. Если приложение не успевает обрабатывать подключения, вы просто делаете буфер больше. Это даст время, но не бесконечную защиту. Хорошая диагностика здесь начинается с простого вопроса: сервер не справляется с валидной нагрузкой или его забивают незавершенными SYN? Потому что снаружи это выглядит одинаково: TCP-порт открыт, а подключиться нормально уже нельзя.
#tcp #network
🧑💻 NetworkAdmin