PHP + Apache долгое время ожидания
Я наткнулся на небольшую кирпичную стену с устранением неполадок моего специального веб-сервера. Недавно мой сайт набрал количество запросов в секунду, и он упал.
Оригинальная коробка имела 8 ГБ оперативной памяти, 8-ядерный Xeon E3-1230, 1 ТБ 7200 об / мин диск (без рейда), 100 Мбит выделенной сети.
После всплеска я увеличил объем ОЗУ до 24 ГБ, чтобы поддерживать более одновременных пользователей.
Apache, кажется, справляется хорошо, даже с 3000 одновременно работающих пользователей, он очень быстро вернет HTML и статический контент (без кэширования).
Для дальнейшего тестирования различий между Apache/HTML и Apache/PHP я запустил ab
,
И то и другое test.html
а также test.php
имеют одинаковый статический контент, PHP не вызывает include
с и не соединяется с MySQL.
Тест HTML
ab -n 500 -c 50 http://www.~~.com/test.html
Connection Times (ms)
min mean[+/-sd] median max
Connect: 252 375 190.3 276 1399
Processing: 254 354 121.5 282 657
Waiting: 253 353 121.4 280 653
Total: 510 730 231.7 573 1675
Тест PHP
ab -n 500 -c 50 http://www.~~~.com/test.php
Connect: 248 275 51.1 267 1316
Processing: 256 4167 6210.2 2262 41489
Waiting: 253 4166 6210.2 2262 41489
Total: 509 4442 6212.4 2523 41754
Pingdom также сообщает о длительном времени ожидания при доступе к скрипту PHP.
Я получаю аналогичный результат на WebPageTest.org, хотя лучше, когда первый байт - F:
Load Time **First Byte** Start Render DOM Elements Time Requests Bytes In Time Requests Bytes In
First View 2.061s **0.839s** 0.000s 55 2.061s 20 428 KB 2.061s 20 430 KB
Вот мой top
Результаты:
I / O Test
При большой нагрузке wa% может увеличиться до 95% за несколько миллисекунд.
Я запускал iostat во время загрузки:
avg-cpu: %user %nice %system %iowait %steal %idle
8.37 0.00 5.18 0.56 0.00 85.88
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb 0.00 45.50 3.00 48.00 136.00 748.00 17.33 3.05 59.76 2.53 12.90
sdb1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb3 0.00 45.50 3.00 48.00 136.00 748.00 17.33 3.05 59.76 2.53 12.90
avg-cpu: %user %nice %system %iowait %steal %idle
4.00 0.00 3.56 0.69 0.00 91.75
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb 6.00 118.50 9.50 21.00 996.00 1116.00 69.25 0.29 9.44 1.66 5.05
sdb1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb3 6.00 118.50 9.50 21.00 996.00 1116.00 69.25 0.29 9.44 1.66 5.05
Для меня это не выглядит плохо, но я могу что-то упустить.
я использую FCGI
<IfModule mod_fcgid.c>
FcgidMaxRequestLen 1547483648
FcgidMaxRequestInMem 52485760
FcgidIdleScanInterval 15000
FcgidBusyTimeout 15000
FcgidProcessLifeTime 7200
FcgidConnectTimeout 1800
FcgidIOTimeout 1800
PHP_Fix_Pathinfo_Enable 1
FcgidMaxRequestsPerProcess 1000
</IfModule>
А вот и мой Apache Conf (я использую 2.4.x)
Timeout 60
TraceEnable Off
ServerSignature Off
ServerTokens ProductOnly
FileETag None
StartServers 10
<IfModule prefork.c>
MinSpareServers 5
MaxSpareServers 15
</IfModule>
<IfModule itk.c>
MinSpareServers 5
MaxSpareServers 15
</IfModule>
ServerLimit 2200
MaxRequestWorkers 2000
MaxConnectionsPerChild 15000
KeepAlive On
KeepAliveTimeout 1
MaxKeepAliveRequests 2000
Я просмотрел свои журналы ошибок Apache и журналы доступа. Ничего странного, чтобы сообщить.
Я действительно чешу голову здесь.
Я пытался отключить брандмауэр.
Я пытался увеличить Макс подключений.
Я оптимизировал MySQL и удалил много медленных запросов (которые были>0,5 с).
Что еще я могу сделать, есть ли что-то, что я могу использовать, чтобы помочь идентифицировать проблемы? Любая помощь будет принята с благодарностью.
PS:
Стоит отметить, что даже при интенсивном доступе к серверу PHPMyAdmin и cPanel по-прежнему очень отзывчивы. Ничто другое, кажется, не отстает, кроме PHP на сайте.
2 ответа
Я думаю, что ваша проблема - просто ваш жесткий диск с временем доступа. Apache может кэшировать html-страницы в памяти, но php-скрипты не кэшируются; необходимость быть выполненным каждый раз снова. Поэтому вызывается интерпретатор php, который читает скрипт с жесткого диска. Это занимает много времени. Самая медленная вещь на вашем сервере - ваш жесткий диск. На моем компьютере существует крайняя разница между приложениями, начиная с моего SSD и моего HDD (SSD работает до 10 раз быстрее!). Если ваш жесткий диск работает, то задержка выполнения скрипта php может резко возрасти.
Возможные решения: получите SSD (возможно, небольшой, только для часто используемых данных, таких как сценарии) и минимизируйте вызовы сценариев (и обращения к HDD) на вашем сервере. Убедитесь, что файловая система дефрагментирована (обычно это делается автоматически). Если ваш php-скрипт часто создает одно и то же содержимое, попробуйте кэшировать их в html-файл.
Этот ответ также может помочь вам: https://stackoverflow.com/questions/4181865/apache-php-caching
HTML-файл, который вы тестируете, - это простой файл, все, что нужно сделать Apache, это сделать несколько системных вызовов (открыть, прочитать) и затем обработать его содержимое.
PHP OTOH на самом деле довольно "тяжелый" вариант: это целый интерпретатор (компилятор байт-кода?). А поскольку вы используете параллельное тестирование (-c), кто знает, насколько хорошо к нему мультиплексированы запросы? Это вовсе не проблема apache, а проблема PHP.
Что бы я сделал:
Переключитесь на Apache MPM (многопоточный в нескольких процессах).
Сделайте последовательный тест (без нескольких одновременных запросов), сравните.
Бежать
valgrind
или что-то подобное в процессе Apache и посмотреть, где больше всего процессорного времени (Apache или PHP).запустить тот же тест, но обслуживая эту страницу через nginx. Поскольку nginx основан на асинхронной модели и очень быстр, то, если вы получите схожие результаты, виновником является PHP.
Наконец, вы можете установить Zend Optimizer (30-дневная пробная версия бесплатно) или что-то вроде этого: https://github.com/zendtech/ZendOptimizerPlus.
Действительно, сравнение подачи статического файла с динамически генерируемой веб-страницей - это своего рода сравнение яблок и апельсинов. Ни одно из типичных решений (Python mod-apache, Django, PHP и т. Д.) Не будет очень быстрым в этом отношении, по крайней мере, по сравнению с обработкой статического файла. Node.js, возможно, является исключением из-за своего рода "низкоуровневой" веб-страницы программирования непосредственно в асинхронной модели.
PS ты не цитировал php.ini
содержание. Опубликовать и / или настроить его.