SystemdDoctor
мешает работе сокеты нагрузка

Сокет с ReusePort: соединения распределяются неравномерно

Параметр повторного использования порта позволяет нескольким процессам слушать один адрес: ядро распределяет соединения между ними. Это удобно для масштабирования, но распределение не идеально равномерное, и при разном числе экземпляров получается перекос.

Вероятные причины

По порядку: сверху то, что встречается чаще.

  1. Экземпляры запущены не одновременно

    Ядро распределяет новые соединения между текущими слушателями. Экземпляр, поднявшийся позже, получает меньше, пока не установятся новые соединения.

  2. Соединения долгоживущие

    Распределение работает при установке соединения. Постоянные соединения закрепляются за одним экземпляром надолго.

  3. Параметр не поддерживается программой

    Программа должна открывать сокет с нужным флагом. При сокет-активации это делает systemd параметром сокета.

Диагностика

Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.

Сколько процессов слушает адрес.

sudo ss -tlnp | grep порт

Общее число соединений на порту.

sudo ss -tan | grep порт | wc -l

Решение

Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.

1. Экземпляры запущены не одновременно
Почему происходит
Ядро распределяет новые соединения между текущими слушателями. Экземпляр, поднявшийся позже, получает меньше, пока не установятся новые соединения.
Как проверить
Посмотрите число соединений по процессам.
sudo ss -tlnp | grep :8080
sudo ss -tan | grep :8080 | wc -l
Как исправить
Для долгоживущих соединений перекос сохраняется. Балансировщик впереди даёт более предсказуемое распределение, чем повторное использование порта.
2. Соединения долгоживущие
Почему происходит
Распределение работает при установке соединения. Постоянные соединения закрепляются за одним экземпляром надолго.
Как проверить
Посмотрите время жизни соединений.
sudo ss -tno | grep :8080 | head
Как исправить
Ограничьте время жизни соединений или поставьте перед службой балансировщик, который умеет их перераспределять.
3. Параметр не поддерживается программой
Почему происходит
Программа должна открывать сокет с нужным флагом. При сокет-активации это делает systemd параметром сокета.
Как проверить
Посмотрите параметр сокета.
systemctl show myapp.socket -p ReusePort 2>/dev/null
Как исправить
Задайте ReusePort=yes в описании сокета либо включите соответствующую настройку в самой программе.

Пример вывода

Два экземпляра на одном порту, распределение неравномерно. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.

$ sudo ss -tlnp | grep :8080
LISTEN 0 4096 *:8080 *:* users:(("myapp",pid=1200,fd=6))
LISTEN 0 4096 *:8080 *:* users:(("myapp",pid=1340,fd=6))

$ sudo ss -tan | grep -c "1200"
412
$ sudo ss -tan | grep -c "1340"
88

$ systemctl show myapp.socket -p ReusePort
ReusePort=yes

Связанные ошибки

Где встречается чаще всего

Источники

  • systemd.socket(5)
    ReusePort= и распределение соединений.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Проверено двумя экземплярами службы с повторным использованием порта.
    собственная проверка, systemd 255
    сверено 15 сентября 2026