Символы Capistrano, кэшированные?

Я настраивал развертывание PHP с Capistrano на CentOS 6 и столкнулся с интересной проблемой. Как работает capistrano, он устанавливает такие папки:

  • /var/www/myapp.com/
    • current (символическая ссылка на последнюю версию в релизах)
    • общие
    • релизы
      • 20130826172737
      • 20130826172114

Когда я смотрю на "текущую" символическую ссылку, она указывает на самую последнюю версию. Сначала, открывая мое веб-приложение, все работало нормально. После развертывания новой версии папка current правильно указывает на новую версию, но веб-приложение пытается загрузить файлы из старой версии (которая была удалена в процессе очистки Capistrano). Кроме того, виртуальный хост настроен на /var/www/myapp.com/current/Public.

Символы привязаны каким-либо образом?

Конкретный PHP-код, который терпит неудачу (который инициализирует мою структуру), таков:

require_once dirname(dirname(__FILE__)) . '/App/App.php';
App\App::run();

Это находится в index.php, расположенном в настоящее время в /var/www/app.com/current/Public/index.php.

Мои журналы ошибок Apache показывают:

PHP Неустранимая ошибка: require_once(): не удалось выполнить открытие '/var/www/myapp.com/releases/20130826172237/App/App.php' (include_path = '.:/usr/share/pear:/usr/share/php ') в /var/www/myapp.com/releases/20130826172237/Public/index.php

И символическая ссылка current показывает:

current → /var/www/zverse/релизы/20130826172641

Очевидно, что 20130826172641!= 20130826172237, последний из которых был предыдущей версией.

Любые идеи или области, на которые я могу смотреть?

Ответ 1

Я не могу это проверить, но кажется, что существует некоторое непредсказуемое поведение с Apache после/кэширования старого расположения символических ссылок:

Единственное, что полностью прояснило эту проблему, - это цикл Apache, который мы бы предпочли не делать при каждом развертывании. - Майк Бриттен

Он предлагает переместить весь каталог вместо обновления символической ссылки.

Ответ 2

Вы проверили директивы realpath_cache_size и realpath_cache_ttl? По умолчанию php > 5.1 кэширует реальные пути символических файлов в течение 120 секунд. Это вызовет проблемы с развертыванием capistrano. Основными проблемами являются кэширование - даже если вы очистите свой кеш, ваши старые php файлы будут по-прежнему обслуживаться в течение двух минут, переполняя их старыми данными и взаимодействием между php и статическими файлами. Статические файлы обслуживаются непосредственно Apache, поэтому они будут немедленно обновлены. PHP-код по-прежнему будет из предыдущей версии в течение двух минут после развертывания, поэтому он будет ожидать старые версии любых измененных статических файлов. Это особенно проблема, если вы используете процедуру разбиения кэша, которая изменяет имена этих файлов; в этом случае PHP-код не сможет найти файлы, которые он ожидает вообще.

Во всяком случае, есть два решения. Первый заключается в том, чтобы установить truepath_cache_size в 0 в php.ini. (Примечание: установка realpath_cache_ttl на 0 не отключает кеш.) Или, если вы хотите, чтобы он был включен, вы должны иметь возможность использовать clearstatcache, чтобы очистить кеш реального пути сразу же после развертывания вашей символической ссылки, используя крюк capistrano. Имейте в виду, что если вы используете mod_php, время автономной работы php cli и apache раздельно, поэтому вам нужно будет вызвать эту функцию с помощью PHP скрипт, вызванного apache, аналогично тому, что сделано для очистка кэша APC здесь. Я не тестировал это, хотя, поскольку я не заметил значительного влияния производительности, просто отключив кеш.