2013-08-26 4 views
12

나는 CentOS 6에서 Capistrano로 PHP 배치를 설정하고 흥미로운 문제가 발생했습니다. 방법 카피 스트라 노의 작품은,이 같은 폴더를 설정합니다Capistrano Symlinks Cached?

  • /var/www/myapp.com/
    • 출시 을 공유
    • 전류 (IN/릴리스 최신 버전에 심볼릭 링크)
      • 20130826172737
      • 20130826172114

"현재"심볼릭 링크를 보면 가장 최근의 릴리스를 가리 킵니다. 처음에는 웹 응용 프로그램을 열 때 모든 것이 정상적으로 작동했습니다. 새 릴리스를 배포 한 후 현재 폴더의 폴더가 새 릴리스를 올바르게 가리키고 있지만 웹 응용 프로그램은 이전 릴리스 (Capistrano 정리 프로세스에서 삭제됨)에서 파일을로드하려고 시도합니다. 또한 가상 호스트는 /var/www/myapp.com/current/Public을 가리 키도록 구성됩니다.

어떤 방식 으로든 심볼릭 링크가 캐시되어 있습니까?

(내 프레임 워크를 초기화) 실패 특정 PHP 코드는 이것이다 : 현재 /var/www/app.com/current/Public에있는 index.php를

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

/index.php.

내 아파치 오류 로그를 보여

PHP Fatal error: require_once(): Failed opening required '/var/www/myapp.com/releases/20130826172237/App/App.php' (include_path='.:/usr/share/pear:/usr/share/php') in /var/www/myapp.com/releases/20130826172237/Public/index.php

그리고 현재 심볼릭 링크 쇼 : 후자는 이전 버전을했다

분명히 20130826172641

current -> /var/www/zverse/releases/20130826172641

= 20130826172237!.

내가 볼 수있는 아이디어 나 영역은 무엇입니까?

+1

딸꾹질 인 것 같습니다. 나는 약 10 분을 기다렸다가 다시 시험해 보았다. 그것이 일종의 아파치 최적화 였는지 궁금하다. –

+0

PHP의 realpath 캐시를 비활성화하거나 [mod_realdoc] (https://github.com/etsy/mod_realdoc)을 사용하면이 문제는 서버를 다시 시작하지 않고도 사라집니다. – Mahn

+0

CentOS에서 nginx 서버와 동일한 문제가 발생하면 '현재'심볼릭 링크가 최신으로 업데이트되지 않습니다. – Nimbosa

답변

4

나는 이것을 확인할 수 있지만, 아파치가 다음/심볼릭 링크의 이전 위치 캐싱 일부 예기치 않은 동작이 보인다 :

The only thing that would absolutely clear up this issue was to cycle Apache, which we would prefer not to do on every deployment. -- Mike Brittain

그는 심볼릭 링크를 업데이트하는 대신 전체 디렉토리를 옮길 것을 제안합니다.

+2

정보를 제공해 주셔서 감사합니다. 나는 아직도이 문제를 자주 겪고 있지만, Capistrano 배포 프로세스의 일부로 문제를 해결할 것으로 보이는'service httpd restart'를 만들었습니다. –

+1

'service httpd reload' /'systemctl reload apache2.service'는 가동 중지 시간이 없으며 동일한 효과가 있습니다. – smcjones

+0

감사합니다 @smcjones - 답변을 수정 하시겠습니까/그것을 커뮤니티 답장으로 만드시겠습니까? 나는 현재 이것을 시험해 볼 수있는 위치에 있지 않다. – ptim

4

realpath_cache_size 및 realpath_cache_ttl 지시문을 확인 했습니까? 기본적으로 php> 5.1은 symlink 된 파일의 실제 경로를 120 초 동안 캐시합니다. 이로 인해 카피 스트라노 배치에 문제가 발생할 것입니다.주요 문제는 캐싱입니다. 캐시를 지우더라도 기존의 PHP 파일은 2 분 동안 계속 제공되고 이전 데이터로 다시 채워지며 PHP와 정적 파일 간의 상호 작용이 계속됩니다. 정적 파일은 Apache에서 직접 제공되므로 즉시 업데이트됩니다. PHP 코드는 배포 후 2 분 동안 이전 릴리스에서 계속 남아 있기 때문에 변경된 정적 파일의 이전 버전을 기대하게됩니다. 이러한 파일의 이름을 변경하는 캐시 분리 절차를 사용하면 특히 문제가됩니다. 이 경우 PHP 코드는 기대하는 파일을 찾을 수 없습니다.

어쨌든, 두 가지 해결책이 있습니다. 첫 번째는 php.ini에서 realpath_cache_size를 0으로 설정하는 것입니다. (참고 : realpath_cache_ttl을 0으로 설정하면 이 캐시되지 않습니다. 캐시를 사용하지 않으려면 clearstatcache 함수를 사용하여 심볼 링크를 배포 한 직후에 capistrano hook을 사용하여 realpath 캐시를 지울 수 있어야합니다 (참고 : realpath_cache_ttl을 0으로 설정하면이 캐시를 비활성화합니다). . 비록 mod_php를 사용하고 있다면, PHP cli와 아파치 런타임은 분리되어 있으므로, clearing the APC cache here의 경우와 마찬가지로 아파치에 의해 호출 된 PHP 스크립트를 사용하여 해당 함수를 호출해야합니다. 캐시를 단순히 사용 불가능으로 설정하면 성능에 큰 영향을 미치지 않으므로 테스트하지 않았습니다.

+0

realpath 캐시와 APC 캐시 채우기 사이의 정확한 상호 작용에 대한 생각, 사후 통보? apc_clear_cache()는 php-fpm 풀의 전체 (공유 메모리) 캐시를 지우지 만 clearstatcache (true)는 특정 php-fpm 프로세스의 realpath 캐시만을 지울 것입니다. 사용중인 시스템에서 4 개의 php-fpm 프로세스를 실행 중이면 다른 3 개는 이전 데이터에서 다시 채울 수 있습니까? – jrg

+1

@jrg 나는 당신이 무엇을 요구하고 있는지 정확히 알지 못합니다. APC 캐시와 realpath 캐시는 별개의 두 가지 문제입니다. APC를 클래스 맵용으로 사용하거나 그와 같은 새로운 코드 개정판을 재배포 할 때 APC가 무효화되는 경우 배포 할 때 APC를 지워야합니다. realpath 캐시는 별도이고 php 심볼릭 링크를 참조하기 때문에 clearstatcache를 실행하지 않는 한 다시 배포 한 후에 파일의 이전 위치를 사용합니다. 실제로 그 하나의 PHP 프로세스에 대한 realpath 캐시를 지우는 경우 (내가 말했던 것처럼 테스트하지는 않았다) 모든 것을 지우는 방법이 필요하다. –

+0

@jrg 웹 서버를 다시 시작하지 않고 어떻게 수행할지 확실하지 않습니다. (개인적으로 realpath 캐시를 비활성화하는 것만으로도 성능에 아무런 영향을 미치지 않는 것으로 나타났습니다. 다시 APC 캐시와 구별됩니다.) APC 또는 다른 캐시를 사용하여 클래스 맵을 캐시하는 경우 또는 어떤 PHP 디렉토리, 당신은 realpath 캐시를 지우고 즉시 지울 필요가있다; 그렇지 않으면 이전 값에서 다시 채워집니다. –

관련 문제