Я наткнулся на кирпичную стену при устранении неполадок на моем выделенном веб-сервере. Недавно на моем веб-сайте резко увеличилось количество запросов в секунду, и он завис.
В оригинальной коробке было 8 ГБ ОЗУ, 8 Core Xeon E3-1230, 1 ТБ диск 7200 об / мин (без Raid), 100 Мбит выделенная сеть.
После всплеска я увеличил ОЗУ до 24 ГБ, чтобы поддерживать большее количество одновременных пользователей.
Apache, кажется, справляется хорошо, даже при 3000 одновременных пользователей, он очень быстро возвращает HTML и статический контент (без кеширования).
Чтобы еще больше проверить различия между Apache / HTML и Apache / PHP, я запустил ab
.
Обе test.html
и test.php
имеют точно такое же статическое содержимое, PHP не вызывает никаких include
s и не соединяется с 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 тест
При большой нагрузке 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 с).
Что еще я могу сделать, могу ли я чем-нибудь помочь в выявлении проблем? Любая помощь будет принята с благодарностью.
P.S:
Стоит отметить, что даже при интенсивном обращении к серверу PHPMyAdmin и cPanel по-прежнему очень отзывчивы. Кажется, больше ничего не тормозит, кроме PHP на сайте.
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, возможно, является исключением из-за своего рода "низкоуровневой" веб-страницы программирования непосредственно в асинхронной модели.
P.S. вы не цитировали php.ini
содержание. Опубликуйте и / или настройте.
Я думаю, ваша проблема - это просто ваш жесткий диск с его временем доступа. Apache может кэшировать html-страницы в памяти, но php-скрипты не кешируются; необходимость выполнять каждый раз заново. Поэтому вызывается интерпретатор php, который читает сценарий с жесткого диска. На это уходит много времени. Самая медленная вещь на вашем сервере - это жесткий диск. На моем компьютере существует огромная разница между приложениями, начинающимися с моего SSD и моего жесткого диска (SSD работает до 10 раз быстрее!). Если ваш жесткий диск работает, то задержка выполнения php-скрипта может резко возрасти.
Возможные решения: приобретите SSD (возможно, небольшой, только для часто используемых данных, таких как скрипты) и минимизируйте количество вызовов скриптов (и обращений к HDD) на вашем сервере. Убедитесь, что файловая система дефрагментирована (обычно выполняется автоматически). Если ваш php-скрипт часто создает одно и то же содержимое, попробуйте кэшировать его в html-файл.
Этот ответ также может вам помочь: https://stackoverflow.com/questions/4181865/apache-php-caching