Я запускаю http-сервер Apache 2.4 с PHP 7.0 и MySQL 5.5 на Debian GNU / Linux 8 (jessie). Иногда Apache полностью перестает отвечать на запросы в течение нескольких секунд - около 30 секунд или больше. В это время запросы, похоже, выстраиваются в очередь - и когда Apache, наконец, снова начинает нормально работать, нужно обрабатывать сразу много накопившихся запросов, что, конечно, тоже не так хорошо.
Причина, по которой Apache перестает отвечать на запросы, неясна, потому что:
echo "Hello World!";
не выполняетсяОЗУ вроде в порядке - раздел подкачки много не используется. Это то, что top
говорит во время стойла:
KiB Mem: 6129344 total, 5975748 used, 153596 free, 24 buffers
KiB Swap: 1952764 total, 199428 used, 1753336 free. 4397256 cached Mem
Я попытался проанализировать проблему с помощью strace - если быть точным, когда я замечаю, что сервер перестает отвечать, я ввожу в оболочку:
ps auxw | grep apache | awk '{print" -p " $2}' | xargs sudo strace
Я заметил, что в это время строки, подобные приведенным ниже, довольно часто видны в выводе strace, чего не бывает в тех случаях, когда проблема отсутствует:
[pid 13521] fcntl(57, F_SETLK, {type=F_RDLCK, whence=SEEK_SET, start=1073741824, len=1}) = -1 EAGAIN (Resource temporarily unavailable)
Обычно, когда проблем нет, я вижу такие строки:
[pid 3414] fcntl(55, F_SETLK, {type=F_RDLCK, whence=SEEK_SET, start=1073741824, len=1}) = 0
Кто-нибудь знает, что это значит? Мне кажется, есть какой-то конфликт блокировок ...
Для полноты, вот моя конфигурация Apache:
LogFormat "%h PID %P %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\" %V" common
ServerTokens ProductOnly
ServerSignature Off
TraceEnable off
<IfModule mod_ssl.c>
SSLHonorCipherOrder On
SSLProtocol ALL -SSLv2 -SSLv3
SSLCipherSuite EECDH+AES:AES256-SHA:AES128-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH:!EXP:!SRP:!DSS:!LOW;
SSLVerifyClient none
SSLVerifyDepth 1
SSLInsecureRenegotiation Off
</IfModule>
ScriptAlias /cgi-bin52/ /usr/share/phpcgi/php52/
ScriptAlias /cgi-bin53/ /usr/share/phpcgi/php53/
ScriptAlias /cgi-bin54/ /usr/share/phpcgi/php54/
ScriptAlias /cgi-bin55/ /usr/share/phpcgi/php55/
ScriptAlias /cgi-bin56/ /usr/share/phpcgi/php56/
ScriptAlias /cgi-bin70/ /usr/share/phpcgi/php70/
Mutex flock
LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so
LoadModule status_module /usr/lib/apache2/modules/mod_status.so
AcceptFilter http none
AcceptFilter https none
ExtendedStatus on
TimeOut 60
KeepAlive Off
MaxKeepAliveRequests 50
KeepAliveTimeout 2
Options Indexes MultiViews FollowSymLinks
MaxRequestWorkers 256
MaxRequestsPerChild 300
Видите ли, уже есть запись, связанная с поведением блокировки: Mutex flock
... по его словам, это было предварительно настроено моим веб-хостером из соображений стабильности. Также на https://httpd.apache.org/docs/2.4/mod/core.html#mutex , кажется, это один из немногих вариантов, в котором нет проблем.
Я добавил AcceptFilter
записи при попытке найти решение, но безуспешно.
Может ли кто-нибудь объяснить, какую строку я зарегистрировал, используя strace, содержащий fcntl ...
Значит, или предложить другой метод анализа проблемы?
Вы можете видеть в strace
какой номер файла блокируется. Когда вы делаете ls -l /proc/$pid/fd
вы увидите все открытые файлы для этого процесса. Символьная ссылка с номером файла будет указывать на рассматриваемый файл.
Я видел такие проблемы, обычно это файл сеанса, который имеет эту проблему. Если это файл сеанса, пусть ваши разработчики поймут, что session_write_close()
в PHP делает и что пропускает session_write_close()
сделает вашу работу под нагрузкой.
fcntl - это ядро, пытающееся установить дескрипторы файлов. Одна вещь, на которой вы не сосредоточились, - это время ожидания ввода / вывода диска, поэтому запустите iostat или mpstat, чтобы увидеть, есть ли какие-либо проблемы с производительностью диска, когда вы столкнетесь с проблемами.