ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

Linux sockets: somaxconn, backlog и лимиты файлов (fs.file-max, ulimit nofile)

При пиках трафика ошибки Connection refused и таймауты возникают даже на сильном сервере из‑за переполнения backlog и лимитов FD. Разберём somaxconn, tcp_max_syn_backlog, fs.file-max, ulimit nofile и LimitNOFILE с проверкой в nstat/ss и /proc.
Linux sockets: somaxconn, backlog и лимиты файлов (fs.file-max, ulimit nofile)

Когда веб‑сервис «упирается» в сеть, симптомы часто выглядят одинаково: часть клиентов получает Connection refused, часть — таймауты, в логах появляются сообщения про переполненные очереди, а графики CPU и RAM при этом выглядят вполне прилично. Виноваты обычно не «плохой интернет» и не «слабый сервер», а несогласованные лимиты на очереди принятия соединений и количество файловых дескрипторов.

Разберём три узла, которые чаще всего требуют согласованной настройки: backlog в приложении (или веб‑сервере), системный потолок net.core.somaxconn, а также лимиты дескрипторов fs.file-max и ulimit для nofile. Отдельно затронем net.ipv4.tcp_max_syn_backlog, который влияет на поведение при всплесках новых TCP‑подключений.

Если хотите глубже про общую логику настройки сетевых параметров ядра, держите под рукой: практика sysctl для сетевого тюнинга Linux.

Модель очередей: где на самом деле возникает «очередь на вход»

В TCP сервер обычно делает три шага: socket()bind()listen(backlog). Параметр backlog задаёт размер очередей на стороне ядра для входящих соединений. Это важно: очереди живут в ядре, а не в процессе приложения.

На практике удобно мыслить двумя очередями:

  • SYN backlog — очередь полуоткрытых соединений (SYN получен, рукопожатие ещё не завершено). На неё влияет net.ipv4.tcp_max_syn_backlog.
  • Accept backlog — очередь уже установленных соединений, которые ждут, пока приложение вызовет accept(). На неё влияют net.core.somaxconn и параметр backlog в listen().

Если переполняется SYN backlog — клиенты чаще видят таймауты установки соединения (повторы SYN, рост времени connect). Если переполняется accept backlog — ядро может начать отклонять соединения, что часто выглядит как ECONNREFUSED или как резкий рост ошибок у балансировщика.

net.core.somaxconn и backlog: почему выставили 65535, а стало 4096

net.core.somaxconn — это системный предел (cap) для значения backlog в listen(). То есть приложение может попросить backlog хоть 100000, но ядро ограничит фактическое значение сверху net.core.somaxconn.

Практический вывод: «backlog tuning» — это всегда минимум из двух величин: listen(backlog) в приложении и net.core.somaxconn в ядре.

Проверяем текущие значения

sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog
sysctl net.ipv4.tcp_syncookies

Значение net.ipv4.tcp_syncookies обычно стоит держать включённым (1), но воспринимать как «страховку», а не как замену нормальным очередям и способности приложения принимать соединения.

Как увидеть, что очередь действительно переполняется

Смотрите статистику TCP и события переполнения listen‑очередей.

ss -s
netstat -s | sed -n '1,200p'

На современных системах удобно через nstat (из пакета iproute2):

nstat | egrep 'ListenOverflows|ListenDrops|TCPAbortOnMemory|TCPSynRetrans|TCPTimeouts'

Если растут ListenOverflows и ListenDrops — это почти прямое указание на проблемы с accept backlog (или на то, что приложение не успевает делать accept()).

Настройка somaxconn (временно и постоянно)

Временно (до перезагрузки):

sysctl -w net.core.somaxconn=4096

Постоянно — через файл в /etc/sysctl.d/:

printf '%s
' 'net.core.somaxconn = 4096' | tee /etc/sysctl.d/99-sockets-backlog.conf
sysctl --system

Частые рабочие значения: 1024, 4096, 8192. Очень большие числа «на всякий случай» обычно не ломают систему напрямую, но могут маскировать проблему в приложении (оно не успевает принимать соединения) и увеличивать потребление памяти на очереди в пике.

Если вы планируете тюнинг sysctl и лимитов systemd без ограничений окружения, удобнее делать это на отдельном сервере: на VDS вы полностью контролируете параметры ядра и service‑лимиты под вашу нагрузку.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Схема очередей SYN backlog и accept backlog в Linux

tcp_max_syn_backlog: защита от всплесков новых соединений

net.ipv4.tcp_max_syn_backlog ограничивает размер очереди полуоткрытых соединений (SYN backlog). Она критична для сервисов, где много коротких коннектов: API, фронтенды без keepalive, сервисы за NAT/промежуточными устройствами, которые часто рвут соединения, а также при резких всплесках трафика.

Если у вас растут задержки именно на установке соединения (connect time), а не на обработке запроса, и параллельно видно увеличение повторов SYN, имеет смысл поднять tcp_max_syn_backlog.

sysctl -w net.ipv4.tcp_max_syn_backlog=8192

Постоянно:

printf '%s
' 'net.ipv4.tcp_max_syn_backlog = 8192' | tee -a /etc/sysctl.d/99-sockets-backlog.conf
sysctl --system

Важное уточнение про SYN cookies

SYN cookies помогают пережить переполнение SYN backlog, но это режим деградации. Если постоянно упираетесь в SYN backlog — сначала найдите причину всплесков и согласуйте очереди и параметры сервиса.

fs.file-max и ulimit nofile: почему «всё настроили», а сокеты не открываются

Даже если очереди backlog идеальны, приложение всё равно может «упереться» в файловые дескрипторы. В Linux сокет — это файловый дескриптор. Когда заканчиваются FD, начинаются ошибки уровня «Too many open files», нестабильность accept(), проблемы с логами/резолвингом/прокси‑коннектами — в зависимости от того, что именно не смогло открыть новый FD.

Лимиты здесь многослойные:

  • fs.file-max — системный лимит на число файловых дескрипторов во всей системе.
  • ulimit для nofile (RLIMIT_NOFILE) — лимит на количество открытых файлов для конкретного процесса/пользователя.
  • На systemd‑системах дополнительный «потолок» часто задаётся в unit через LimitNOFILE.

Проверяем текущие значения и фактическое потребление

sysctl fs.file-max
cat /proc/sys/fs/file-nr
ulimit -n

Файл /proc/sys/fs/file-nr обычно содержит три числа: выделено, свободно (или unused) и максимум. Трактовка второго поля между версиями ядра менялась, но для практики важны первое и третье: приближается ли «выделено» к максимуму.

Быстро прикинуть, кто «съедает» FD (топ‑20 процессов):

ls -1 /proc | grep -E '^[0-9]+$' | while read p; do printf '%s ' "$p"; ls -1 /proc/$p/fd 2>/dev/null | wc -l; done | sort -k2 -n | tail -n 20

Поднимаем fs.file-max

Временно:

sysctl -w fs.file-max=2097152

Постоянно:

printf '%s
' 'fs.file-max = 2097152' | tee /etc/sysctl.d/99-fd-limits.conf
sysctl --system

Число выбирайте от профиля нагрузки. Для веб‑узла с большим количеством одновременных соединений (и ещё, например, с проксированием на апстримы) «миллион+» дескрипторов на систему — нормальная планка, если хватает памяти и вы понимаете, какие процессы реально могут их потреблять.

ulimit nofile: поднимаем лимит для сервиса (systemd)

Частая ловушка: вы увеличили fs.file-max, но процесс всё равно ограничен, например, 1024 или 4096. На systemd‑системах корректнее задавать лимит в unit‑файле.

Проверить лимит процесса можно так (подставьте PID):

cat /proc/PID/limits | sed -n '1,200p'

Настройка через systemd override (рекомендуется, чтобы не править пакетный unit):

systemctl edit nginx

Добавьте:

[Service]
LimitNOFILE=200000

Затем примените:

systemctl daemon-reload
systemctl restart nginx

Подход одинаковый для nginx, php-fpm, gunicorn, node, java и любых прокси: повышайте LimitNOFILE именно там, где работает процесс, который держит соединения.

Как связать всё вместе: практический чеклист «backlog tuning»

Смысл настройки — не «подкрутить все ручки вверх», а согласовать лимиты так, чтобы они не противоречили друг другу и соответствовали реальной модели нагрузки.

Шаг 1. Поймите, где именно узкое место: SYN или accept

  • Растут ListenOverflows/ListenDrops — смотрите net.core.somaxconn и backlog приложения, плюс способность приложения быстро делать accept().
  • Растут повторы SYN/таймауты коннекта — смотрите net.ipv4.tcp_max_syn_backlog, состояние сети и профиль всплесков новых соединений.

Шаг 2. Проверьте backlog на стороне приложения/веб‑сервера

Например, у Nginx есть директива listen ... backlog=. У некоторых рантаймов и фреймворков backlog задаётся параметром или имеет консервативное значение по умолчанию. Если приложение просит backlog=128, то повышение net.core.somaxconn выше 128 само по себе не даст эффекта.

При этом помните: огромный backlog может увеличить «хвост» задержек при перегрузе — соединения будут дольше висеть в очереди, прежде чем их примут и обслужат. Иногда быстрый отказ лучше, чем «длинная очередь» и массовые таймауты.

Шаг 3. Убедитесь, что хватает FD

Типичная картина при нехватке FD: сервис перестаёт принимать новые соединения не потому, что очередь мала, а потому что ему нечем открыть новый сокет. Тогда можно бесконечно поднимать backlog, но проблема останется.

Мини‑проверка:

ulimit -n
sysctl fs.file-max
cat /proc/sys/fs/file-nr

Шаг 4. Нагрузочный тест и валидация метрик

После изменения параметров сделайте контролируемый тест (пусть даже короткий) и сравните метрики «до/после»:

  • ошибки соединения у клиента/балансировщика;
  • ListenOverflows/ListenDrops;
  • время установления соединения (connect) и TTFB;
  • количество открытых FD у процесса и по системе.

Если вы балансируете не HTTP, а TCP/UDP (например, базы, очереди, кастомные протоколы), полезно свериться с настройками стрим‑прокси: балансировка TCP/UDP в Nginx stream.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Частые ошибки и безопасные ориентиры

Ошибка 1: подняли somaxconn, но не изменили лимит на FD в сервисе

На systemd чаще всего «фактическая» проблема в LimitNOFILE, а не в fs.file-max. Начинайте с проверки /proc/PID/limits после рестарта сервиса.

Ошибка 2: лечат симптомы, а не причину перегруза

Переполнение accept backlog бывает из‑за того, что приложение не успевает обрабатывать запросы или слишком медленно вызывает accept(). Тогда повышение backlog лишь увеличит очередь ожидания, но не увеличит пропускную способность. Параллельно ищите «почему медленно»: блокировки, пул воркеров, база данных, диски, DNS, upstream‑задержки.

Ошибка 3: не учитывают, что соединение — это не один FD

В прокси‑сценариях (например, Nginx → upstream) один клиентский коннект часто означает минимум один FD на фронте плюс один на апстриме. Добавьте логи, файлы статики, резолвер, unix‑сокеты — и требование к ulimit для nofile растёт быстро.

Мониторинг переполнения listen-очередей и потребления файловых дескрипторов

Быстрый шаблон настроек для веб‑узла (как отправная точка)

Ниже — не «универсально лучший», а адекватный старт для сервера, который должен переживать пики новых подключений и держать много одновременных соединений. Дальше значения корректируются по метрикам.

cat > /etc/sysctl.d/99-sockets-and-fd.conf << 'EOF'
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
fs.file-max = 2097152
EOF
sysctl --system

Отдельно выставьте LimitNOFILE в unit ваших ключевых сервисов (веб‑сервер, приложение, прокси), затем проверьте, что процесс после рестарта действительно получил новый лимит через /proc/PID/limits.

Итог: что держать в голове

net.core.somaxconn и backlog решают разные части проблемы, но работают в связке: приложение просит очередь, ядро ограничивает. net.ipv4.tcp_max_syn_backlog помогает переживать всплески установления новых TCP‑соединений. А fs.file-max и ulimit для nofile определяют, сможет ли сервис вообще открывать новые сокеты и файлы под нагрузкой.

Самый практичный подход: зафиксировали симптомы, посмотрели nstat, проверили FD‑лимиты, согласовали значения, повторили тест. Так вы получите предсказуемое поведение при пиках, а не «магическую» настройку, которая работает только в спокойное время.

Поделиться статьей

Вам будет интересно

Incident response для сайта: что делать, если website hacked и найден malware OpenAI Статья написана AI (GPT 5)

Incident response для сайта: что делать, если website hacked и найден malware

Если сайт взломали, действуйте по плану: быстро изолируйте узел, сохраните логи и артефакты до чистки, выполните log review, убери ...
Docker volumes: backup/restore, prune и bind-mount — практический гид OpenAI Статья написана AI (GPT 5)

Docker volumes: backup/restore, prune и bind-mount — практический гид

Docker volumes кажутся простыми, пока не понадобятся бэкап, перенос на другой сервер или чистка диска. Разбираем volume vs bind-mo ...
IPv6 DNS: AAAA и reverse DNS (ip6.arpa) — практическая настройка и диагностика OpenAI Статья написана AI (GPT 5)

IPv6 DNS: AAAA и reverse DNS (ip6.arpa) — практическая настройка и диагностика

Пошагово разбираем DNS для IPv6: как публиковать AAAA, как устроен reverse DNS в ip6.arpa и как собрать PTR-имя из IPv6-адреса. Да ...