Мы пытаемся развернуть новый код PHP через Capistrano во время работы Opcache.
Capistrano создает новый каталог развертывания при каждом развертывании, а затем настраивает символическую ссылку, чтобы веб-сервер указывал на новый каталог. Поскольку Opcache кэширует по реальному пути к файлу, это означает, что вновь развернутая версия сайта кэшируется полностью отдельно от старой.
Проблема, с которой мы сталкиваемся, заключается в том, что Opcache исчерпывает память, потому что каждое новое развертывание приводит к кешированию полной базы кода, а старый код никогда не удаляется. Мы могли бы позвонить opcache_reset()
, но когда кеш сбрасывается, мы кратко получаем 500 ошибок, когда кеши бегут. (У нас также будут те же ошибки, если мы попытаемся запустить новое развертывание без прогрева кэша.)
Есть ли лучший способ справиться с этим? Некоторый способ запустить новый код, не заполняя opcache до тех пор, пока он не исчерпает память (или не очищается сам, потому что у него слишком много файлов), что позволяет нам избежать вызова opcache_reset()
на живом сайте? Мы используем (или в любом случае пытаемся перейти на) Nginx в качестве нашего веб-сервера с PHP-FPM, обрабатывающим запросы PHP.
Вариант будет позвонить opcache_invalidate
для каждого из файлов в старой версии сайта в конце развертывания. Вы можете предотвратить кэш-печать, включив файл после аннулирования.
Второй вариант — настроить fpm на наличие нескольких пулов и перезапустить их один за другим (они начнут с чистого opcache). Вы несколько предотвратите паническое бегство кеша: только один сервер будет иметь чистый кеш в любой момент времени, и приложение будет работать, потому что nginx сможет сбалансировать нагрузку на различные пулы.
Другой вариант — удалить старые версии скрипта, чтобы opcache очищал их из кэша после прохождения revalidate_freq, заставляя загружать новые файлы из файловой системы.
Других решений пока нет …