У меня есть веб-сайт на базе WordPress, работающий на виртуальном хостинге. Его время отклика очень приличное (около 2 с для получения HTML-страницы и 5 с для загрузки всех ресурсов).
Я планировал перенести его на выделенный виртуальный сервер (Ubuntu 12.04 LTS), что теоретически должно улучшить ситуацию и сделать их более согласованными, учитывая, что он не используется совместно. Однако я наблюдал серьезное снижение производительности, когда для создания страницы требовалось 10 секунд.
Я исключил проблемы с сетью, отредактировав /etc/hosts
на сервере и сопоставление домена с 127.0.0.1
. Я использовал тестер нагрузки Apache ab
чтобы получить HTML, чтобы исключить JS, CSS и изображения. Все равно прошло 10 секунд.
У меня Zpanel установлен на сервере, который также использует MySQL, и его страницы появляются довольно быстро (1,5 с), а также phpMyAdmin. Выполнение некоторых запросов к базе данных wordpress напрямую через phpMyAdmin также возвращает их довольно быстро, со временем запроса в диапазоне от 10 до 30 миллисекунд.
Памяти также достаточно: из доступных 1 ГБ физической памяти используется только 800 МБ, так что это тоже не проблема подкачки. Я также установил APC, чтобы попытаться улучшить производительность PHP, но это не помогло.
Что еще мне следует искать? Что могло вызвать такое снижение производительности? Может быть, это какая-то проблема ввода-вывода, поскольку я работаю на виртуальном сервере в облаке?
Я хотел бы обсудить этот вопрос со своим провайдером, но, не показывая фактических данных какого-либо диагноза, я боюсь, что он просто обвинит мое приложение.
ОБНОВИТЬ с участием sar
вывод (каждую секунду), когда я выполнял HTTP-запрос:
02:31:29 CPU %user %nice %system %iowait %steal %idle
02:31:30 all 0.00 0.00 0.00 0.00 0.00 100.00
02:31:31 all 2.22 0.00 2.22 0.00 0.00 95.56
02:31:32 all 41.67 0.00 6.25 0.00 2.08 50.00
02:31:33 all 86.36 0.00 13.64 0.00 0.00 0.00
02:31:34 all 75.00 0.00 25.00 0.00 0.00 0.00
02:31:35 all 93.18 0.00 6.82 0.00 0.00 0.00
02:31:36 all 90.70 0.00 9.30 0.00 0.00 0.00
02:31:37 all 71.05 0.00 0.00 0.00 0.00 28.95
02:31:38 all 14.89 0.00 10.64 0.00 2.13 72.34
02:31:39 all 2.56 0.00 0.00 0.00 0.00 97.44
02:31:40 all 0.00 0.00 0.00 0.00 0.00 100.00
02:31:41 all 0.00 0.00 0.00 0.00 0.00 100.00
ОБНОВЛЕНИЕ 2 После предложений Йостена.
Ввод / вывод:
iotop
терпит неудачу с OSError: Netlink error: No such file or directory (2)
и sar -d
также не справляется с Requested activities not available in file /var/log/sysstat/sa14
. Я думаю, это потому, что это виртуальная машина, как и iostat
тоже не получается. Может быть, это причина, почему %iowait
сообщает sar 1 10
всегда 0%?
Загрузка процессора:
Процесс, превышающий% ЦП в htop
на самом деле apache2
. Я ожидал, что это может быть база данных, но это не так. Когда я делаю новый HTTP-запрос, он увеличивается до 94% за несколько секунд. Кажется, в этом виноват.
Я сделал strace -f -t
и одно резюме strace -c -f
. Кажется, очень много lstat
вызывает (57786), при этом 2455 приводит к ошибкам. Не знаю, нормально ли это. Помимо этого, самый верхний вызов был wait4
что, как я полагаю, нормально (это просто ожидание), и munmap
. Топ 5 ниже.
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
51.06 0.124742 897 139 6 wait4
14.90 0.036388 1 57786 2455 lstat
9.67 0.023622 13 1857 munmap
7.69 0.018790 37 514 brk
6.70 0.016361 481 34 clone
2.87 0.006999 74 94 12 select
strace
сам по себе замедлил apache в 2 раза. Сейчас я пытаюсь разобраться в длинной трассировке, чтобы увидеть, есть ли что-нибудь, указывающее на то, что вызывало скачок производительности процессора в течение нескольких секунд.
Какое типичное время для lstat
для хорошо работающего сервера? Я хочу собрать некоторую информацию, чтобы я мог конструктивно пожаловаться поставщику, если это ошибка доступа к хранилищу.
ОБНОВИТЬ Выход fio
тест случайного чтения:
random-read: (g=0): rw=randread, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
random-read: Laying out IO file(s) (1 file(s) / 128MB)
Jobs: 1 (f=1): [r] [100.0% done] [12185K/0K /s] [2975 /0 iops] [eta 00m:00s]
random-read: (groupid=0, jobs=1): err= 0: pid=24264
read : io=131072KB, bw=10298KB/s, iops=2574 , runt= 12728msec
clat (usec): min=119 , max=162219 , avg=380.34, stdev=957.37
lat (usec): min=119 , max=162219 , avg=380.89, stdev=957.40
bw (KB/s) : min= 7200, max=13424, per=99.89%, avg=10285.72, stdev=1608.68
cpu : usr=2.80%, sys=18.65%, ctx=33511, majf=0, minf=23
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=32768/0/0, short=0/0/0
lat (usec): 250=45.57%, 500=37.17%, 750=3.41%, 1000=7.83%
lat (msec): 2=5.67%, 4=0.27%, 10=0.08%, 20=0.01%, 250=0.01%
Run status group 0 (all jobs):
READ: io=131072KB, aggrb=10297KB/s, minb=10545KB/s, maxb=10545KB/s, mint=12728msec, maxt=12728msec
Единственный намек, который у меня есть сейчас, это то, что линейка процессоров fio
По сравнению с другими системами вывод, похоже, демонстрирует довольно большую активность. Я запустил его на своей локальной машине с Ubuntu, и результат был:
cpu : usr=0.19%, sys=0.59%, ctx=32923, majf=0, minf=23
В usr
процент кажется небольшой частью того, что сообщается на моем сервере.
ОБНОВИТЬ Re PHP APC. Да, он установлен. Вывод из phpinfo:
APC Support enabled
Version 3.1.7
APC Debugging Disabled
MMAP Support Enabled
MMAP File Mask no value
Locking type pthread mutex Locks
Serialization Support php
Revision $Revision: 307215 $
Build Date May 2 2011 19:00:42
Есть ли какой-то конкретный параметр, который я должен проверить? Это настройки, которые у меня есть (локальное значение, главное значение):
apc.cache_by_default On On
apc.canonicalize On On
apc.coredump_unmap Off Off
apc.enable_cli Off Off
apc.enabled On On
apc.file_md5 Off Off
apc.file_update_protection 2 2
apc.filters no value no value
apc.gc_ttl 3600 3600
apc.include_once_override Off Off
apc.lazy_classes Off Off
apc.lazy_functions Off Off
apc.max_file_size 1M 1M
apc.mmap_file_mask no value no value
apc.num_files_hint 1000 1000
apc.preload_path no value no value
apc.report_autofilter Off Off
apc.rfc1867 Off Off
apc.rfc1867_freq 0 0
apc.rfc1867_name APC_UPLOAD_PROGRESS APC_UPLOAD_PROGRESS
apc.rfc1867_prefix upload_ upload_
apc.rfc1867_ttl 3600 3600
apc.serializer default default
apc.shm_segments 1 1
apc.shm_size 32M 32M
apc.slam_defense On On
apc.stat On On
apc.stat_ctime Off Off
apc.ttl 0 0
apc.use_request_time On On
apc.user_entries_hint 4096 4096
apc.user_ttl 0 0
apc.write_lock On On
ОБНОВИТЬ Вырос apc.shm_size
до 96М. Счетчик полного кэша теперь равен 0, и 96,5% попаданий в кеш после нескольких обновлений веб-сайта здесь и там. Объем памяти APC составляет 25,4 МБ.
Кажется, время загрузки сократилось примерно на 3 секунды, а теперь до 4-5 секунд, если я сделаю чистый wget
с самого сервера без получения изображений и т. д. Все еще более чем в два раза медленнее, чем на другом хостинге, но определенно было улучшением.
Я все еще нахожу странным, почему на отображение этих страниц уходит так много времени, когда сервер полностью простаивает (у меня не установлен APC на моем компьютере разработки, и у него нет такого поведения). И все еще странно, куда тратятся лишние оставшиеся секунды.
Вы должны сначала определить, в чем проблема; если это PHP, MySQL, ввод-вывод, нагрузка, память, процессор, ядро и т. д. sar
регистрирует системные метрики; вам придется поймать это с поличным. Вы можете настроить atop
вести учет процессов, что определенно помогает.
Чтобы определить, является ли это ввод / вывод
Используйте такие инструменты, как iotop
и atop
чтобы узнать, как используется диск; эти инструменты также расскажут вам, что вызывает ввод-вывод. Как правило, если iowait устойчивый более 10% это может быть проблемой.
sar
регистрирует ввод-вывод диска; так что ты можешь бежать sar -d
чтобы увидеть это (посмотри на %util
столбец).
Чтобы определить, загружен ли он
Используйте такие инструменты, как htop
, top
, uptime
; снова свяжите это с запущенным процессом и узнайте более подробную информацию о том, что делает процесс. Обратите внимание, что это сообщает о нагрузке на планировщик; это не отражает использование ЦП.
Чтобы определить, процессор ли это
sar
снова приходит, чтобы спасти положение; вы можете увидеть эту информацию с помощью sar -P ALL
. Вы также можете использовать mpstat -P ALL
для данных в реальном времени. Как правило, ЦП является проблемой только в том случае, если все ЦП работают на 100%; 80% + означает, что они используются (но не обязательно насыщены).
Чтобы определить, является ли это память (ВМ)
Вы захотите использовать vmstat
; vmstat -S M 1
и соблюдать swap
, io
, и system
столбцы. Очевидно, что большое количество подкачки может повлиять на производительность. Также есть system
раздел; большое количество прерываний также может делать то же самое.
Чтобы определить, прерывает ли он
Ты можешь использовать vmstat -S M 1
. К сожалению, трудно сказать, являются ли прерывания проблемой, если в вашей системе нет исходный уровень на что нормально. Большое количество прерываний (вызванных аппаратным обеспечением, требующим действий со стороны ядра) заставит систему «сканировать». Неудачные сетевые адаптеры печально известны тем, что делают это.
Чтобы определить, ядро ли это
Это сложнее, но обычно требует strace
, perf
, или sysdig
инструменты. Одним из таких инструментов является perf top
. strace
с резюме (-c
) приятно, но не разбивает его относительно системных ресурсов (так что предоставленные данные являются лишь предположениями); это идеально для использования perf top
прийти к выводу, что это ядро. Вы также можете использовать stap
(SystemTap), если ваш компьютер поддерживает его. Я также должен отметить, что strace
повлияет на производительность; ты должен использовать sysdig
если система вообще важна.
Чтобы определить, является ли это MySQL / PHP
Вы в основном должны следовать тому, что я написал выше (perf
например, может предоставить информацию о том, какая команда вызывает большое время ядра, iotop
, atop
, htop
может предоставлять информацию относительно системных ресурсов о том, что их использует); в основном, вы используете вышеуказанные инструменты, чтобы определить причину нагрузки.
Как только вы определили, что это MySQL
Это может быть запрос, который вы выполняете (поэтому вы захотите использовать EXPLAIN
по этому запросу в MySQL). Вам также необходимо убедиться, что ваша база данных оптимизирована и запросы, которые вы выполняете, оптимизированы. Вы также должны убедиться, что движок таблиц, который вы используете, идеально подходит для того, что вы делаете (я видел много больших таблиц, использующих MyISAM, хотя они должны быть InnoDB). Если вы определили, что ничего из вышеперечисленного не является проблемой, и все еще подозреваете, что MySQL, вы можете захотеть заархивировать данные в затронутых таблицах, чтобы уменьшить доступ (сканирование таблиц) к этой таблице. Вы также можете проверить согласованность ограничений, включить буферизацию кеша и убедиться, что индексы оптимальны.
Хорошим инструментом для помощи в этом процессе является mytop
; но вся информация, что mytop
обеспечивает легко доступный в mysql
клиент. Некоторые полезные операторы для запуска:
SHOW FULL PROCESSLIST\G
чтобы получить на сервере полный список выполняемых в данный момент операторов SQL, а также их статус.SHOW ENGINE INNODB STATUS\G
(Только InnoDB)EXPLAIN EXTENDED <QUERY>
чтобы объяснить запрос, который выполняется MySQL.SHOW GLOBAL STATUS\G
для общесерверного статусаКак только вы определили, что это PHP
Вы можете использовать инструменты для профилирования вашего PHP-кода (например, xdebug
), а затем откройте созданный профиль в KCacheGrind
чтобы увидеть анализ производительности профилированного кода PHP.
Если вы обнаружите, что это не так, возможно, вам просто нужно обновить сервер.
Одним из основных источников ввода-вывода для сайтов с интенсивным трафиком является /tmp
Ввод / вывод, происходящий из:
/tmp
читается для данных сеанса php для многих систем CMS, таких как WordPress, при каждом переходе страницы, чтобы определить, имеет ли посетитель право доступа к новой странице
/tmp
много раз записывается / читается для любого SQL SELECT, в котором возвращаемые данные или любые созданные временные выбранные наборы находятся в / tmp
Первое, что я делаю при переносе клиента с медленной машины на новую (надеюсь, более быструю) машину - это размер памяти. Мой быстрый 30-секундный алгоритм:
(используется верхняя память + используется своп) * 2
Затем на новой машине я настраиваю /tmp
вбежать tmpfs (память) + использование mysqltuner (каждые несколько дней) + настраивать mysql (действительно mariadb) до mysqltuner в основном тихо.
Иногда этого простого трюка достаточно, чтобы вдохнуть новую жизнь в медленно работающий сервер.
Как только это будет сделано, а затем, если машина все еще работает медленно, я начинаю настраивать каждую подсистему.
При настройке я всегда начинаю с инструмента, который сообщает мне текущее состояние.
Поэтому для изменения размера памяти используйте top (память + подкачка + загрузка).
Для Apache, проверьте журналы, чтобы убедиться, что в них нет таких сообщений, как превышение MaxRequestWorkers.
Для старых PHP версии используют монитор APC, чтобы убедиться, что APC действительно работает + имеет достаточно свободной памяти + высокий процент попаданий - 90% + - хорошая цель.
Для современных версий PHP сделайте то же самое для Opcache, который несколько лет назад пришел на смену APC.
Для MySQLсначала переключитесь на MariaDB (по моему опыту, намного быстрее) + используйте mysqltuner каждые несколько дней, пока не получите достаточно тихий вывод.
Для CMS как и WordPress, никогда не верьте никому на слово, чтобы узнать, какой плагин кэширования работает. Используйте ab для проверки скорости сайта, сначала без кеширования + добавьте плагин кеширования + повторное тестирование.
Подсказка: начните с ZenCache + и вы удивитесь.
Наконец, я имитирую медиллорис DDOS атаковать каждый новый сервер, который я настраиваю, поскольку поведение DDOS работает по-разному в зависимости от схемы сети + скорости адаптера + ресурсов машины. Я настраиваю системы так, чтобы они выдерживали атаки DDOS достаточно долго, чтобы коды состояния Apache 4xx (обычно 400 + 408) отображались в журналах Apache + использую fail2ban для блокировки этих IP-адресов.
Большая часть настройки ввода-вывода - это создание необычных ситуаций загрузки, таких как slowloris DDOS, перед развертыванием любых сайтов на машине. Таким образом, вы можете настраиваться на досуге, вместо того, чтобы пытаться настраиваться под реальной нагрузкой, такой как расходы на рекламу или получение Slashdotted ... или под атакующей нагрузкой, такой как DDOS или High Value Attack, или просто злой скребок, который игнорирует ваш robots.txt
+ высасывает все ресурсы из вашей машины.
Оглянись ответ, который я дал на другой вопрос похож на этот для подсказок.
Дело в том, что если другие страницы за пределами области WordPress загружаются нормально, но сам WordPress задыхается, на ум приходят три вещи помимо общих вещей, которые я рекомендую.
wp-config.php
? Причина в том, что иногда WordPress может работать, несмотря на неправильные пути, если они установлены в параметрах MySQL DB для WordPress. Убедившись, что они в wp-config.php
заставляет WordPress использовать правильные каталоги и гарантирует, что временные папки и папки кеша работают должным образом.my.cnf
работает должным образом для нужд БД вашего сайта?В общем, я без проблем установил множество сайтов CMS - в последнее время WordPress - на облачных серверах. загрузка страницы 10 секунд не является признаком неадекватности облачного хоста. Я бы рекомендовал просмотреть то, что я рекомендую здесь и в другом своем ответе. И я также рекомендовал бы отладить, выполнив чистую установку WordPress в настройке, которая является проблемой, и посмотреть, как она отреагирует. Если это хорошо работает по сравнению с вашим полным сайтом, то очевидно, что в коде вашего сайта есть некоторые проблемы с конфигурацией.
РЕДАКТИРОВАТЬ: Вот еще одна идея. Есть ли у вас авторизация Apache (htaccess) где-нибудь в вашей настройке? У вас настроено разрешение от localhost
? Увидеть ниже. Иногда эта настройка работает, но если Allow from localhost
является первым в списке Allow
Или единственный элемент в списке Allow
Это может задохнуться от странности обратного DNS. Я бы порекомендовал попробовать отключить это - если вы можете - и посмотреть, насколько быстро загружается сайт по сравнению с тем, как он был включен.
Order Deny,Allow
Deny from all
Allow from 127.0.0.1 ::1
Allow from localhost
Это похоже на другие случаи, которые я видел, когда Apache тратит много времени на компиляцию PHP. Вы убедились, что установлен кеш-код операции (например, APC)? Он будет отображаться как загруженный модуль на выходе phpinfo()
, если это поможет. В противном случае, чтобы отслеживать, что делает Apache в mod_php, лучшим вариантом будет XHProf.
Для всех, кроме jbx, прибывающих сюда через Google: кстати, другие ответы отличные. Иди прочитай их. Но эти ответы и ответы jbx на них помогли мне прийти к такому выводу.