%20%D1%80%D0%B0%D1%81%D1%82%D1%83%D1%82%20-%20%22%D1%82%D0%B0%D0%B1%D0%BB%D0%BE%20%D0%B7%D0%B0%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%BE%22.png)
Запуск MPM-воркера, Apache 2.4.46, Debian 9
Изящно завершающиеся воркеры просто растут со временем, они, кажется, никогда не заканчиваются. В конце концов у меня заканчивается емкость и появляется ошибка "scoreboard is full". Если я перезапускаю apache, они освобождаются.
Я не думаю, что это как-то связано с кодом моего сайта (php), так как многие из зависших запросов представляют собой просто чистые GET-запросы изображений, без какого-либо участия PHP.
<IfModule mpm_worker_module>
ServerLimit 500
StartServers 10
MinSpareThreads 50
MaxSpareThreads 100
ThreadLimit 64
ThreadsPerChild 64
MaxRequestWorkers 500
MaxConnectionsPerChild 0
</IfModule>
apache в течение недели, количество бесплатных слотов сокращается
пробовал с включенным и выключенным сохранением активности
решение1
При использовании MPM Worker запросы обрабатываются потоками, существующими в процессах.
Отhttps://httpd.apache.org/docs/2.4/mod/worker.html
Один процесс управления (родительский) отвечает за запуск дочерних процессов. Каждый дочерний процесс создает фиксированное количество потоков сервера, как указано в директиве ThreadsPerChild, а также поток-слушатель, который прослушивает соединения и передает их потоку сервера для обработки по мере их поступления.
В Linux процесс «содержит» потоки, то есть один PID может иметь несколько потоков, которые совместно используют память (помимо других ресурсов) с другими потоками в этом PID.
На самом деле, Linux заботится только о «задачах», немногопоточный процесс — это PID с контейнеромодинзадача.
Когда вы изящно перезагружаете Apache, вы завершаете содержащий его процесс. Здесь происходит следующее: Apache заставляет каждый поток ждать, пока все потоки в содержащем процессе не завершатся, прежде чем перезапустить PID контейнера.
Итак, в вашем случае у вас есть один поток, содержащийся во всех процессах в этом списке, который все еще занят или каким-то образом завис.
У вас есть несколько вариантов.
- Просто перестаньте ждать и начните заново.
- Найдите проблемную тему (возможно, это ошибка в приложении) и исправьте ее.
1, легко. Добавьте параметр конфигурации GracefulShutdownTimeout
со значением, которое является высоким, но не глупым. Скажем, 900 секунд. По умолчанию это бесконечно, что означает, что ваши потоки будут ждать вечно, пока ваш проблемный поток не завершится.
Главный недостаток этого в том, что вы сталкиваетесь с вероятностью прерывания процесса в середине выполнения чего-то критического — завершение которого может в свою очередь повредить файл или незаметно сломать приложение. Вы также сталкиваетесь с (исчезающе малым) шансом завершить клиент на полпути обработки.
2, вам придется обнаружить поток, застрявший в списке рабочих процессов, а затем диагностировать, что делает соединение, но вы обязательно обнаружите то, что может быть недостатком конструкции, и сможете более уверенно объяснить поведение, прежде чем просто удалить проблемный поток.