다운 타임없이 웹앱 업데이트


31

PHP 앱입니다. 전체 코드베이스를 업데이트하는 동안 다운 타임을 최소화하려면 어떻게해야합니까?

답변:


44

우리가 직장에서 일반적으로하는 일은 :

  • 업데이트하기 전에 서버의 문서 루트는 다음과 같습니다.
    • ...에서 /www/app-2009-09-01
    • 그러나 심볼릭 링크를 통해 액세스됩니다. /www/application
  • 우리는 완전히 새로운 코드베이스를 /www/app-2009-09-08
  • 전체 코드베이스가 있으면 :
    • 이전 심볼릭 링크를 제거합니다
    • 우리는 여전히 새로운 심볼릭 링크를 만듭니다. /www/application 만 새로운 소스를 가리 킵니다./www/app-2009-09-08
  • 수정 사항을 강제로 적용하기 위해 아파치를 다시로드합니다.

이 모든 과정은 자동 스크립트를 통해 수행됩니다 (자동이 아닌 유일한 방법은 필요할 때 시작하는 것입니다). 이것은 다음을 의미합니다.

  • 모든 것이 빠르게 진행됩니다 (특히 심볼릭 링크 전환, 중요한 부분 임)
  • 오류의 위험이 없음 : 스크립트가 잘 테스트되었으며 몇 개월 / 년 동안 작업


이 심볼릭 링크 절차의 또 다른 장점은 새 버전의 소스를 프로덕션에 배치 한 후에 만 ​​치명적인 버그를 발견 한 경우 업데이트를 "롤백"하는 것이 매우 쉽다는 것입니다. 심볼릭 링크를 다시 전환하면됩니다.

물론 이것이 스테이징 서버에서 프로덕션에 넣기 전에 새 버전을 테스트하는 것을 방해하지는 않습니다. 그러나 누가 아는가? 때로는 아무도 볼 수 없었던 큰 버그가 있습니다. testing :-(
예를 들어, 스테이징 머신에서 정기적으로로드 테스트가 수행되지 않기 때문에 ( "롤백"항목은 3 년 동안 4 ~ 5 번 사용되는 것을 보았습니다 .
매번, 하루를 저장-웹 사이트 ^^)


다음은 간단한 예입니다. Apache 구성에이 VirtualHost가 있다고 가정하십시오.

<VirtualHost *>
        ServerName example.com
        DocumentRoot /www/application
        <Directory /www/application>
            # Whatever you might need here (this example is copy-pasted from a test server and test application ^^ )
            Options Indexes FollowSymLinks MultiViews +SymLinksIfOwnerMatch
            AllowOverride All
            php_value   error_reporting 6135
            php_value short_open_tag  on
        </Directory>
</VirtualHost>

꽤 "표준"... 유일한 것은 /www/application실제 디렉토리가 아닙니다. 단지 현재 버전의 소스에 대한 심볼릭 링크 일뿐입니다.
즉, 소스를 서버에 넣었지만 아직 전환하지 않은 경우 다음과 같은 내용이 표시됩니다.

root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:08 application -> /www/app-2009-09-01

symlinc은 "이전 버전"을 가리 킵니다.

이제 새 버전이 서버에 완전히 업로드되었으므로 다음과 같이 전환 해 보겠습니다.

root@shark:/www
# rm /www/application
root@shark:/www
# ln -s /www/app-2009-09-08 /www/application

그리고 이제 /www/application소스의 새 버전을 가리 킵니다.

root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:09 application -> /www/app-2009-09-08

그리고 우리는 Apache를 다시 시작해야합니다.

root@shark:/www
# /etc/init.d/apache2 restart
 * Restarting web server apache2

" 링크 제거; 새 링크 작성; 아파치 재시작 "의 세 단계 는 빠르게 수행되어야합니다. 즉, 사람이 아니라 자동화 된 스크립트에 의해.

이 솔루션 사용 :

  • 새로운 버전의 소스를 업로드하는 데 필요한 시간이 오래 걸릴 수 있습니다.
  • 모든 것이 정상이면 그냥 심볼릭 링크를 전환하십시오 : 1 또는 2 파일조차 변경하는 것보다 빠릅니다 ... 실제로 다운 타임이 없음을 의미합니다 :-)

stat 옵션이 0 인 APC와 같은 opcode-cache를 사용하면 다운 타임 위험이 훨씬 적을 수 있습니다.


물론 이것은 "간단한"버전입니다. 예를 들어, 업로드 된 파일이있는 경우 다른 심볼릭 링크 또는 다른 VirtualHost 등을 사용해야합니다.


희망이 더 분명하다 :-)


일종의 서버 교환입니다. :-)
Wim ten Brink

심볼릭 링크를 관리하기위한 mod_rewrite?

@gAMBOOKa : 아니오 : Apache의 DocumentRoot (또는 VirtualHost DocumentRoot)의 문제인 / www / application ;; 즉, 상징적 링크는 어디를 가리켜도 상관 없습니다.

2
대단한 답변. 그러나 한 가지 더 팁 : 링크를 해제하지 않고 심볼릭 링크를 만들 수 있습니다. 인용 된 바와 같이 : "세 단계는… 즉, 사람이 아니라 자동화 된 스크립트에 의해 신속하게 이루어져야합니다." mv 명령은 원 자성 연산이므로 'ln -s / www / app-2011-01-28 / www / application-temp'와 같은 심볼릭 링크를 만든 다음 'mv -T / www / application-temp / www / application '을 참조하십시오.

1
symlink 방법으로 다루지 않은 것이 있습니다. 길은 Apache + mod_php에서 작동하지만 lighttpd + fastcgi에서는 실패 할 수 있습니다. 트래픽이 많은 웹 사이트에서는 링크를 교체하는 동안 요청이 제공되며, 혼합 버전에서는 PHP 코드 종속성이 실패합니다.
Dennis C

2

기존 코드를 가져와 프로젝트를 별도의 테스트 PHP 파일로 마이그레이션하여 업데이트하는 동안 사용할 수 없습니까? 의미하는 바는 테스트 서버와 프로덕션 서버가 있어야 업데이트 할 때 다운 타임이 발생하지 않도록하는 것입니다.


1

업데이트 된 코드베이스로 두 번째 서버를 설정하고 가능한 빨리 전환하십시오. :-)

가능하지 않으면 코드베이스가 수십 개의 작은 부분으로 나뉘어 있는지 확인하십시오. 그러면 다운 타임은 한 번에 하나의 하위 파트로 제한됩니다. 작은 코드 블록은 교체하기가 쉽고 대부분 문제없이 계속 실행됩니다. 그래도 테스트 환경에서 먼저 시도하십시오!


앱이 조각난 모듈로 테스트되지 않았기 때문에 예기치 않은 시나리오가 발생할 수 있습니다.

이는이 업데이트 이후에 ToDo 목록에 있음을 의미합니다. :-) 더 모듈화하고 모듈별로 업데이트 할 수 있습니다.
Wim ten Brink

1
그것은 할일 목록에 있지만 장기적인 목표입니다. 우리는 젊은 신생 기업이므로 개발 팀 내의 조직은 자연스럽게 시간이 걸립니다. = D

1

우선, 나는 종종 파스칼 마틴의 반응과 비슷한 방법을 사용하고 좋아합니다.

내가 좋아하는 또 다른 방법은 SCM을 사용하여 새 코드를 푸시하는 것입니다. 정확한 프로세스는 SCM 유형 (git vs svn vs ...)에 따라 다릅니다. svn을 사용하는 경우 서버에서 문서 루트로 체크 아웃하는 "온라인"또는 "생산"분기를 만들고 싶습니다. 그런 다음 다른 브랜치 / 태그 / 트렁크에서 새 코드를 푸시 할 때마다 새 코드를 "온라인"브랜치에 커밋하고 문서 루트에서 svn update를 실행하면됩니다. 이를 통해 서버로 올라가거나 내려간 내용과 누가 언제 언제했는지에 대한 완전한 개정 로그가 있으므로 매우 쉽게 롤백 할 수 있습니다. 테스트 상자에서 해당 "온라인"분기를 쉽게 실행할 수 있으므로 푸시하려는 앱을 심사 할 수 있습니다.

이 프로세스는 git 및 기타 SCM 스타일과 유사하며 작업 흐름 스타일에 더 자연스럽게 수정되었습니다.

업데이트를 푸시하지 않고 풀 / 폴링을 원하십니까? cron 작업이나 다른 똑똑한 메커니즘만으로 svn update를 자동으로 실행하십시오.

추가 : 이 프로세스를 사용하여 응용 프로그램이 디스크에 쓴 파일을 백업 할 수도 있습니다. cron 작업이나 다른 메커니즘으로 svn commit을 실행하십시오. 이제 응용 프로그램이 생성 한 파일이 SCM, 수정 버전 기록 등에 백업됩니다 (예를 들어, 사용자가 디스크의 파일을 업데이트하지만 파일을 되돌리려면 이전 수정 버전 만 푸시하십시오).


0

Pascal MARTIN과 비슷한 접근법을 사용합니다. 그러나 여러 버전의 앱을 프로덕션 서버에 업로드하는 대신 방화벽 뒤에 "빌드"를 빌드 번호와 날짜가있는 별도의 디렉토리에 유지합니다. 새 버전을 업로드하려면 "rsync -avh --delay-updates"가 포함 된 간단한 스크립트를 사용합니다. "delay = updates"플래그는 모든 업데이트가있을 때까지 모든 것을 임시 폴더에 업로드 한 다음 전송이 끝날 때 모든 것을 적절한 경로로 한 번에 이동하여 앱이 반쯤 새로운 상태. 프로덕션 사이트에 하나의 앱 버전 만 유지한다는 점을 제외하면 위의 방법과 동일한 효과가 있습니다 (프로덕션 서버에 필수 필수 파일 인 IMO 만있는 것이 가장 좋습니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.