Один из многих компонентов, из которых состоит Codacy, начал время от времени отображать исключение «Слишком много открытых файлов». Это была одна из самых сложных ошибок, с которыми нам приходилось сталкиваться на сегодняшний день, доводившая нас до того, что мы рвали на себе волосы. Сегодня мы поделились тем, как мы это исправили, чтобы вы могли не вытащить свой.

Закрыть открытые ресурсы

Решение, когда вы начинаете получать такого рода исключения, заключается в поиске ресурсов, таких как файлы, сокеты и т. д., которые не были должным образом закрыты.

В нашем коде мы следуем золотому правилу закрытия всего, что мы открываем, но, тем не менее, у нас есть некоторые детали нашего стека Scala + PlayFramework, о которых мы не знали, что вызвало утечку ресурсов.

Источник.из файла

Хотя метод scala.io.Source.fromFile часто используется в однострочниках и соблазнителен для использования в функциональном стиле, он не закрывает открытый файл, если вы не сделаете это явно.

val source = scala.io.Source.fromFile("file.txt") val lines = try { source.mkString } finally { source.close() }

play-ws

Это еще один подлый. Если вы используете play-ws вне игрового приложения и создаете экземпляр NingWSClient и приводите его к WSClient, вам будет интересен этот случай. До версии 2.4 интерфейс WSClient не предоставлял метод закрытия, поэтому можно было бы предположить, что он управляется автоматически. Неправильно, файловый дескриптор остался открытым. Чтобы закрыть его, вы должны привести клиента к NingWSClient как:

wsClient.underlying[NingWSClient].close()

В более новых версиях, чем 2.4, метод предоставляется в интерфейсе WSClient.

Увеличение лимитов системы

Если вы зашли так далеко, возможно, вы начинаете чувствовать себя разочарованным. Вы все сделали правильно, но ваше приложение все равно падает. Не волнуйтесь, это нормально. Некоторым приложениям просто нужно обрабатывать больше файлов, чем установлено по умолчанию в ОС. Остальная часть руководства предназначена для конкретного стека Ubuntu.

ulimit

Системные ограничения для дескрипторов открытых файлов устанавливаются в /etc/security/limits.conf. Вы можете изменить их, отредактировав файл или запустив:

ulimit -Hn 65536 ulimit -Sn 65536

Теперь вы можете проверить, были ли ограничения применены к вашему игровому приложению, запустив:

https://gist.github.com/mrfyda/27a99c1c8a1924bf14d1

Если это не так, возможно, вам не хватает этой строки в файле /etc/pam.d/common-session:

session required pam_limits.so

Системные службы

Если после этих изменений ваше приложение по-прежнему использует исходные ограничения, возможно, вы используете его как службу. Наше приложение инициализировалось скриптом инициализации, который не соблюдает ограничения, установленные в /etc/security/limits.conf. Чтобы заставить его работать, нам пришлось жестко запрограммировать ограничения в скрипте инициализации.

Наконец-то успех! Это была очень тяжелая сессия отладки, которая растянулась на пару дней. Я должен поблагодарить моего приятеля по отладке, резинового утенка, который поддерживает меня в здравом уме во время этого путешествия.

Редактировать: мы только что опубликовали электронную книгу The Ultimate Guide to Code Review на основе опроса 680+ разработчиков. Наслаждаться!

Ссылки:
https://stackoverflow.com/questions/26220391/how-to-have-a-scala-standalone-application-that-uses-the-playframework-libraries
https: //www.playframework.com/documentation/2.4.x/api/scala/index.html#play.api.libs.ws.WSClient
https://rtcamp.com/tutorials/linux/increase -open-files-limit/
http://ubuntuforums.org/archive/index.php/t-1274847.html
http://upstart.ubuntu.com/cookbook/

О кодировании

Codacy используется тысячами разработчиков для ежедневного анализа миллиардов строк кода!

Начать легко — и бесплатно! Просто используйте свою учетную запись GitHub, Bitbucket или Google для регистрации.

"НАЧАТЬ"

Первоначально опубликовано на странице https://www.codacy.com/blog/fixing-a-too-many-open-files-exception/ 7 августа 2015 г.