Назад | Перейти на главную страницу

php-fpm генерировал большую нагрузку при сбросе opcache, рендеринг сервера не отвечал

В последние недели мы столкнулись с негативным явлением при развертывании кода: сервер иногда перестает отвечать на запросы на несколько минут.

Вот пример нагрузки на сервер, когда это произошло:

Единственный связанный журнал, который я могу найти, - это /var/log/php7.2-fpm.log и иногда (но не всегда) я вижу такие записи (примечание: это событие, отличное от показанного выше, но происходит то же самое):

[22-Mar-2019 15:33:50] WARNING: [pool api] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 231 total children
[22-Mar-2019 15:33:52] WARNING: [pool api] server reached pm.max_children setting (250), consider raising it
[22-Mar-2019 15:34:05] WARNING: [pool app] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 47 idle, and 104 total children

Случилось так, что мы выполнили развертывание на этом сервере:

Поэкспериментировав, я смог свести проблему с нагрузками только к следующему: opcache_reset()

Как только я выполняю этот вызов (независимо от каких-либо предыдущих или последующих шагов развертывания, это происходит также изолированно, когда я просто вызываю эту конечную точку), есть вероятность внезапного скачка нагрузки на систему.

Если это произойдет и нагрузка «слишком высока» (я бы сказал, исходя из опыта> 200 или около того), система перестает отвечать на запросы в течение нескольких секунд или минут, в зависимости от того, сколько времени потребуется, чтобы все успокоилось.

Технические характеристики:

Конфигурация PHP-FPM:

Возможно, здесь слишком высокие итоги, намерение состояло в том, чтобы справиться с пиками на отдельных виртуальных хостах, которые иногда.

С помощью htop, система обычно выглядит так:

И обычно нагрузка низкая, если у нас нет этого всплеска, который все связан со сбросом opcache (который я недавно узнал):

Я понимаю, что сброс кеша и теперь все процессы должны его повторно заполнять, потребляет ресурсы процессора.

Но чего я не понимаю:

Вот результат opcache_get_status(false) прямо перед развертыванием:

{
  "opcache_enabled": true,
  "cache_full": false,
  "restart_pending": false,
  "restart_in_progress": false,
  "memory_usage": {
    "used_memory": 67353640,
    "free_memory": 66864088,
    "wasted_memory": 0,
    "current_wasted_percentage": 0
  },
  "interned_strings_usage": {
    "buffer_size": 8388608,
    "used_memory": 5215176,
    "free_memory": 3173432,
    "number_of_strings": 89109
  },
  "opcache_statistics": {
    "num_cached_scripts": 2873,
    "num_cached_keys": 5063,
    "max_cached_keys": 7963,
    "hits": 633581523,
    "start_time": 1553172771,
    "last_restart_time": 1553248200,
    "oom_restarts": 0,
    "hash_restarts": 0,
    "manual_restarts": 6,
    "misses": 9512,
    "blacklist_misses": 0,
    "blacklist_miss_ratio": 0,
    "opcache_hit_rate": 99.9984987161316
  }
}

и вот потом:

{
  "opcache_enabled": true,
  "cache_full": false,
  "restart_pending": false,
  "restart_in_progress": false,
  "memory_usage": {
    "used_memory": 57745856,
    "free_memory": 76471872,
    "wasted_memory": 0,
    "current_wasted_percentage": 0
  },
  "interned_strings_usage": {
    "buffer_size": 8388608,
    "used_memory": 4337168,
    "free_memory": 4051440,
    "number_of_strings": 75163
  },
  "opcache_statistics": {
    "num_cached_scripts": 2244,
    "num_cached_keys": 3925,
    "max_cached_keys": 7963,
    "hits": 5893926,
    "start_time": 1553172771,
    "last_restart_time": 1553265235,
    "oom_restarts": 0,
    "hash_restarts": 0,
    "manual_restarts": 7,
    "misses": 4962,
    "blacklist_misses": 0,
    "blacklist_miss_ratio": 0,
    "opcache_hit_rate": 99.91588245106536
  }
}

Другие вещи, которые я заметил:

Что вызывает эти скачки нагрузки действительно ? Как их избежать?

Обновите после принятия ответа:

В основном просто не вызов opcache_reset и возврат большинства моих настроек параметров opcache к значениям по умолчанию (то есть не навязывание их) исправил это.

Этот шаг был частью моего процесса развертывания буквально на протяжении многих лет. Я попытался выяснить первоначальную причину, и, насколько я мог видеть, она была связана с проблемами развертывания, когда классы ссылались на новый код, который еще не был загружен / обновлен.

Оглядываясь назад, я даже не уверен, что это была настоящая проблема, но вот мы здесь.

По умолчанию PHP проверяет временную метку файла, чтобы сделать запись opcache недействительной. Это можно отключить, и это единственный сценарий, который я могу придумать, в котором opcache_reset() будет использоваться. Конечно, это также вызывает возникшую у вас проблему.

Я рекомендую вернуться к значения по умолчанию:

opcache.validate_timestamps = 1
opcache.revalidate_freq = 2
opcache.revalidate_path = 0