Matrix Synapse может запускаться нормально, а затем перестать принимать соединения, выводить в журнал сообщение «Слишком много открытых файлов» или зависать под нагрузкой. В случае установки systemd, в первую очередь следует проверить ограничение на количество файловых дескрипторов, унаследованное запущенным процессом Synapse. Изменение файла ограничений оболочки ulimitили редактирование файла ограничений PAM обычно не изменяет ограничение для службы, запускаемой systemd.
Описанные ниже шаги относятся к хосту Linux, где Synapse работает как служба systemd. Модуль может называться matrix-synapse.service, matrix-synapse@.service, или каким-либо другим именем, специфичным для пакета. Перед копированием команд подтвердите реальный модуль. Если Synapse работает в Docker, Kubernetes или другом контейнере, см. отдельный раздел ниже.
Что означает сообщение «Слишком много открытых файлов»?
В Linux каждому процессу устанавливается ограничение на количество открытых файловых дескрипторов. Дескриптор может ссылаться на файл, сокет, канал или другой ресурс; следовательно, сетевые соединения также потребляют дескрипторы. Когда процесс достигает своего мягкого предела, попытка открыть или принять другой дескриптор может завершиться ошибкой EMFILE. В Linux также существует отдельное ограничение на количество файлов в общесистемной таблице: исчерпание этого лимита может привести к ошибке ENFILE. Увеличение лимита одной службы Synapse не устранит общесистемный дефицит.
В официальном разделе часто задаваемых вопросов (FAQ) Synapse для администраторов говорится, что высокая активность соединений и федерации может использовать множество файловых дескрипторов, и что исчерпание этих дескрипторов может привести к тому, что сервер перестанет принимать новые TCP-соединения. В рекомендациях упоминается повышение лимита как минимум до 4096 в контексте более старых значений по умолчанию, таких как 1024 или 256. Рассматривайте это как минимальный уровень для устранения неполадок в описанной ситуации, а не как универсальную рекомендацию по пропускной способности для каждого домашнего сервера. Начните с проверки эффективного лимита и фактического использования.
В документации Linux по функциям getrlimit и prlimit описаны мягкие и жесткие ограничения для каждого процесса. В Synapse также есть соответствующая soft_file_limitнастройка; в справочнике по конфигурации Synapse указано значение по умолчанию, равное нулю, что указывает Synapse установить мягкое ограничение равным жесткому ограничению, которое он может использовать.
1. Подтвердите неисправность устройства и проведите диагностику.
Сначала определите фактическое имя службы. Во многих пакетных установках это matrix-synapse.service, но не стоит предполагать это имя, если в вашей установке используется собственный модуль или рабочие процессы.
systemctl list-units --type=service --all | grep -i synapse
systemctl status matrix-synapse.service --no-pager
journalctl -u matrix-synapse.service --since "30 minutes ago" --no-pager
Найдите точную ошибку, время её возникновения и выясните, появляется ли она во время всплеска трафика, активности федерации или перезапуска. Затем проверьте лимит, который в данный момент сообщает systemd:
systemctl show matrix-synapse.service -p LimitNOFILE -p MainPID
LimitNOFILEОтображает установленный диспетчером служб лимит; это не количество открытых в данный момент дескрипторов. Команда оболочки, например, ulimit -nсообщает только текущий лимит оболочки и не является доказательством лимита службы.
2. Увеличьте лимит службы systemd с помощью drop-in
Используйте модуль systemd, чтобы обновления пакетов не требовали редактирования файла юнита поставщика. Приведенное ниже значение является примером и не гарантирует идеального значения для каждого сервера. Выберите ограничение с запасом по сравнению с наблюдаемым пиковым использованием и проверьте совместимость приложения и зависимостей, прежде чем устанавливать необычно высокое значение.
sudo systemctl edit matrix-synapse.service
Добавьте это в раздел «Новые вставки редактора»:
[Service]
LimitNOFILE=65536
Сохраните изменения и выйдите, затем перезагрузите systemd и перезапустите Synapse во время подходящего периода технического обслуживания:
sudo systemctl daemon-reload
sudo systemctl restart matrix-synapse.service
systemctl show matrix-synapse.service -p LimitNOFILE
Одно LimitNOFILEзначение устанавливает как мягкое, так и жесткое ограничение для службы в systemd. В руководстве systemd также допускается использование пары soft:hardзначений. Мягкое ограничение не может превышать жесткое. Прежде чем выбирать очень высокое значение, ознакомьтесь с документацией systemd.exec , в которой отмечаются проблемы совместимости для программ, использующих старый select(2)интерфейс с дескрипторами выше 1023. Не следует предполагать, что каждая библиотека или плагин в вашей системе поддерживает любое произвольное ограничение.
3. Проверьте собственные настройки Synapse и службы обработки запросов.
Если в конфигурации Synapse явно задано soft_file_limitнизкое значение, параметр приложения может удерживать мягкий лимит ниже потолка systemd. Найдите этот ключ в активных файлах конфигурации и включаемых файлах конфигурации. Либо удалите ненужное переопределение, либо установите его намеренно; указанное значение по умолчанию, равное нулю, заставляет Synapse повышать свой мягкий лимит до доступного жесткого лимита.
При многопроцессном развертывании каждый рабочий процесс является отдельным процессом и может запускаться отдельным экземпляром модуля или шаблона. Увеличение лимита основной службы не гарантирует автоматически, что каждый рабочий процесс достигнет заданного лимита. Проверьте фактические имена рабочих модулей с помощью команды `npm install` systemctl list-units, затем примените и проверьте соответствующий модуль для каждой службы, которая в нем нуждается.
Аналогично, настройки в /etc/security/limits.confфайле конфигурации и в оболочке входа в систему, ulimitкак правило, не регулируют системную службу, запускаемую непосредственно systemd. В этом случае измените ограничение ресурсов модуля и проверьте его в процессе, который фактически запустил systemd.
4. Если Synapse работает в контейнере
Переопределение systemd на уровне хоста для другой службы не приводит к автоматическому изменению ограничения на количество файловых дескрипторов в контейнере. Настройте среду выполнения контейнера или уровень оркестрации. В Docker Compose определение службы поддерживает настройку для каждого контейнера ulimits; например:
services:
synapse:
ulimits:
nofile:
soft: 65536
hard: 65536
Это число является иллюстративным; определите его размер, исходя из использования и ограничений хоста. В справочнике по сервису Compose Docker описана эта ulimitsнастройка. Начиная с Docker Engine 29, в примечаниях к выпуску Docker описывается изменение ограничения nofile по умолчанию, связанного с containerd 2.1.5: контейнеры могут получать 1024 вместо предыдущего значения по умолчанию 1 048 576. Если проблема возникла после обновления Engine, проверьте эффективное ограничение контейнеров и явно установите необходимое значение ulimit в конфигурации развертывания. См. примечания к выпуску Docker Engine 29 и справочник по docker run .
5. Проверьте лимит запущенного процесса Synapse.
После перезапуска проверьте ограничение на уровне процесса, а не только конфигурацию systemd. Получите основной PID и проверьте ограничения, сообщаемые ядром:
PID=$(systemctl show --property=MainPID --value matrix-synapse.service)
grep "Max open files" "/proc/$PID/limits"
find "/proc/$PID/fd" -mindepth 1 -maxdepth 1 | wc -l
Если основной PID равен нулю или принадлежит оболочке, а не Synapse, определите процесс Synapse в cgroup службы и проверьте вместо него этот PID. Количество дескрипторов является моментальным снимком; повторите проверку при репрезентативной нагрузке. Убедитесь, что «Максимальное количество открытых файлов» соответствует вашим заданным мягким и жестким ограничениям, количество остается значительно ниже мягкого ограничения, и журнал больше не сообщает об ошибке.
Если счетчик продолжает расти, пока не достигнет нового потолка, ограничение может лишь отсрочить сбой. В разделе часто задаваемых вопросов Synapse отмечается, что зависшие или медленные запросы могут быть важны при исследовании исчерпания файловых дескрипторов. Просмотрите окружающие журналы и обработку запросов, сравните количество дескрипторов с течением времени и исследуйте возможную утечку или неожиданно устойчивые соединения, вместо того чтобы продолжать слепо повышать лимит.
Когда повышения лимита на услугу недостаточно
Если в журналах сообщается об ошибке исчерпания таблицы файлов в масштабе всей системы, например ENFILE, , проверьте использование ресурсов на уровне хоста и других служб; LimitNOFILEизменение для каждой службы отдельно не увеличит общую пропускную способность ядра. Избегайте изменения глобальных ограничений ядра без подтверждения ошибки и понимания ее влияния на весь хост. Если сообщаемый лимит службы остается низким после установки нового модуля, выполните команду systemctl cat matrix-synapse.serviceдля подтверждения загрузки нового модуля, проверьте имя юнита, перезагрузите systemd и перезапустите нужный юнит.
Быстрая самопроверка
- Вы определили, какой именно модуль или контейнер Synapse регистрирует ошибку?
- Сообщает ли
systemctl showустройство о предполагаемом пределе его возможностей?
- Отображаются ли
/proc/<Synapse-PID>/limitsзаданные программные и аппаратные ограничения после перезагрузки?
- Находится ли количество дескрипторов ниже допустимого предела при нормальной пиковой нагрузке?
- Проверяются ли параметры рабочих единиц и настроек контейнеров отдельно, где это применимо?
- Ошибка исчезла, или же использование продолжает расти, приближаясь к новому максимальному уровню?
Если все проверки на уровне процессов пройдены успешно и ошибка прекратилась во время репрезентативного трафика, значит, изменение лимита systemd работает. Если же накопление дескрипторов продолжается или система сообщает о глобальном дефиците, следует продолжить расследование источника проблемы, а не рассматривать увеличение лимита как полное решение.
Источники