план написания сочинения
Будет завершено: Подробная информация о различных используемых инструментах
Автор: Чжу Син
Подходит для чтения толпы
Идеи тюнинга в этой статье используются на php, java или любом другом языке, если у вас есть опыт использования php, то однозначно будет лучше
бизнес фон
Фреймворк и соответствующая среда
- laravel5.7, mysql5.7, redis5, nginx1.15
- centos 7.5 bbr
- docker, docker-compose
- Облако Alibaba 4C и 8G
фон проблемы
PHP включил opcache, laravel также запустил команду optimize для оптимизации, а composer также запустил команду dump-autoload.
Первое, что нужно констатировать, это то, что должны быть небольшие проблемы в окружении системы (без проблем невозможно улучшить такую большую производительность), но эти проблемы можно и не найти за всю жизнь, если не использовать соответствующие инструменты.
В этой статье основное внимание уделяется тому, как найти эти проблемы и как их найти.
Сначала мы находим подходящий API или функцию в системе, чтобы увеличить проблему.
Этот API изначально был разработан для проверки работоспособности балансировки нагрузки nginx. Используя ab -n 100000 -c 1000 для измерения давления, было обнаружено, что qps может достигать только 140 в секунду.
Мы знаем, что производительность Laravel заведомо плохая, но не до такой степени, она не должна быть такой низкой с точки зрения написания API, поэтому мы решили взглянуть.
public function getActivateStatus()
{
try {
$result = \DB::select('select 1');
$key = 1;
if ($result[0]->$key !== 1) {
throw new \Exception("mysql 检查失败");
}
} catch (\Exception $exception) {
\Log::critical("数据库连接失败: {$exception->getMessage()}", $exception->getTrace());
return \response(null, 500);
}
try {
Cache::getRedis()->connection()->exists("1");
} catch (\Exception $exception) {
\Log::critical("缓存连接失败: {$exception->getMessage()}", $exception->getTrace());
return \response(null, 500);
}
return \response(null, 204);
}
Производительность проблем и идеи по устранению неполадок
top
Команда top обнаруживает, что процессор системы занят на 100% Среди них на пользовательский режим приходится 80%, а на режим ядра 20%, что не кажется большой проблемой.Есть одно место, которое выглядит странно, Результат выполнения верхней команды
То есть некоторые процессы php-fpm находятся в состоянии сна, но загрузка процессора по-прежнему достигает почти 30%. Когда процесс находится в состоянии сна, он по-прежнему занимает много ресурсов процессора.Не сомневайтесь, проблема ли это в процессе, давайте посмотрим на справочную страницу команды Ttop.%CPU -- CPU usage
The task's share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time.
Общий смысл в том, что эта загрузка - это загрузка процессора процессом, когда экран обновляется в последний раз.Потому что, когда команда top собирает информацию, linux может принудительно планировать процесс (например, чтобы top собирал информацию о процессе), поэтому в данный момент (в момент обновления экрана) некоторые процессы php-fpm находятся в состоянии сна, что понятно, поэтому это не должно быть проблемой php-fpm.
pidstat
Сначала выберите процесс php-fpm, а затем используйте pidstat для просмотра подробного статуса процесса.
Ничего необычного в процессе обнаружено не было, и результаты запуска команды top были в основном такими же.vmstat
Сохраняя тест давления, запустите vmstate, чтобы увидеть, за исключением переключения контекста (переключение контекста) немного выше, и не видел слишком много исключений. Поскольку docker, redis и mysql, которые мы используем, работают на одной машине, CS около 7000 по-прежнему является разумным диапазоном, но IN (прерывание) слишком велико, достигая около 14 000. Что-то должно быть вызвано прерыванием.
Мы знаем, что существуют аппаратные прерывания и программные прерывания для прерываний.Жесткие прерывания прерываются аппаратными средствами, такими как сетевые карты и мыши, и процессор немедленно останавливает свою работу для обработки сигналов прерывания.Мягкие прерывания выдаются операционной системой и часто используются для форсирования процессов расписания.И vmstat, и pidstat — это просто новые инструменты обнаружения энергии, мы не можем видеть, кто выдал конкретное прерывание. Мы читаем информацию о прерываниях системы через файл только для чтения /proc/interrupts, чтобы узнать, что вызвало увеличение прерываний.С помощью команды watch -d мы можем судить о наиболее часто изменяемых прерываниях.
watch -d cat /proc/interrupts
Мы обнаружили, что прерывания перепланирования изменяются быстрее всего, это прерывание перепланирования (RES), этот тип прерывания указывает, что ЦП в состоянии простоя просыпается, чтобы запланировать выполнение новых задач. Это механизм, используемый планировщиком для распределения задач между различными ЦП в многопроцессорной системе (SMP), также обычно называемый межпроцессорными прерываниями (IPI). Комбинируя команды в vmstat, мы можем определить, что одной из причин низкого qps являетсяСлишком много процессов борются за процессорВ результате мы до сих пор не уверены, что это такое, поэтому необходимо дальнейшее расследование.
strace
strace может просмотреть системный вызов. Мы знаем, что при использовании системного вызова система переходит в режим ядра, и этот процесс будет генерировать мягкое прерывание. Просмотрев системный вызов php-fpm, мы можем проверить нашу гипотезу
В самом деле,Найдено много системных вызовов статистики, мы предполагаем, это вызвано тем, что opcache проверяет, не истек ли срок действия файла.Изменив конфигурацию opcache, мы делаем так, чтобы opcache меньше проверял временную метку файла и уменьшал этот вид системного вызова opcache.validate_timestamps="60"
opcache.revalidate_freq="0"
Выполните команду ab еще раз, чтобы проверить давление
Конечно же, qps вырос сразу до 205, улучшение было очень очевидным, и оно было близко к46%способствовать ростуperf
В настоящее время эта производительность все еще не удовлетворена, и я надеюсь найти прорывы в других местах. пройти через
perf record -g
perf report -g
см. отчет системного анализа
Мы видим, что слишком много системных вызовов, связанных с установлением tcp (не знаю, так ли это, пожалуйста, поправьте меня, но когда я вижу send, ip, tcp и т. д., я подозреваю, что это может быть tcp проблема, связанная с /ip). Мы подозреваем два случая- Неоднократно устанавливать большое количество TCP-соединений с mysql и redis, потребляя ресурсы
- tcp-соединение, вызванное большим количеством запросов
Поговорим о первом.После проверки обнаружено, что соединение с базой данных использует пул соединений php-fpm, а соединение с redis - нет.Предиспользуемый redis предис является чистой реализацией PHP с низкой производительностью, поэтому было заменен на phpredis:
Откройте файл config/database.php laravel, измените драйвер redis на phpredis и убедитесь, что на машине установлено расширение redis для php.Кроме того, поскольку сам Laravel инкапсулирует фасад Redis, имя объекта, полученное расширение Redis также называется Redis, поэтому вам нужно изменить фасад Laravel Redis на другое имя, например RedisL5.
Испытание давлением еще раз
Он достиг удовлетворительных 286 запросов в секунду, хотя по сравнению с другими высокопроизводительными фреймворками или нативным php все еще есть много возможностей для улучшения (например, Swoole), но в конечном итоге он достиг улучшения на 104%, что все еще очень значимо.Суммировать
Через top мы обнаружили, что загрузка ЦП системы высока, и обнаружили, что процесс php-fpm действительно занимает ресурсы ЦП, полагая, что узкое место в системе исходит от PHP.
Затем через pidstat и vmstat мы обнаружили, что в процессе измерения давления произошло большое количество системных прерываний, а черезwatch -d cat /proc/interruptsУстановлено, что основное прерывание исходит от перепланированного прерывания (RES).
Глядя на конкретные системные вызовы через strace, обнаруживается, что большое количество системных вызовов исходит от stat. Предполагается, что opcache часто проверяет метку времени и оценивает модификацию файла. Путем изменения элементов конфигурации улучшение производительности составляет 46%. Достигнут.
Наконец, через perf проверьте стек вызовов функций и проанализируйте его.Возможно, большое количество TCP-соединений с redis приводит к ненужному потреблению ресурсов.Установив расширение redis и используя phpredis для управления кешем Redis Laravel, производительность улучшено и достигнуто Еще одно улучшение производительности почти на 50%.
В конце концов мы достигли нашей цели повышения производительности на 104%.