새로운 코드 라이브 배포


29

라이브 (전자 상거래) 사이트에 새 코드를 배포하는 가장 좋은 방법은 무엇입니까?

지금은 디렉토리 이름 public_html_new을 ~로 바꿀 때 +/- 10 초 동안 아파치를 중지 public_html했습니다 public_html_old. 이것은 Apache를 다시 시작하기 전에 짧은 가동 중지 시간을 만듭니다.

Git을 사용하여 새 저장소를 라이브 디렉토리로 가져 오는 경우에도 동일한 질문이 발생합니다. 사이트가 활성화되어있는 동안 레포를 가져올 수 있습니까? DB를 복사해야한다면 어떨까요?

라이브 사이트의 tar (백업 목적) 압축 중에 미디어 디렉토리에서 변경이 발생했음을 알았습니다. 그것은 파일이 주기적으로 계속 바뀌고 있음을 나타냅니다. 배포 중에 Apache가 중지되지 않으면 이러한 변경이 방해 될 수 있습니다.

답변:


13

로드 밸런서를 사용하는 것이 좋습니다. 사이트가 몇 초의 다운 타임을 걱정할 정도로 중요하다면 내결함성에 대해 걱정할만큼 중요합니다.

그 외에, 이것이 UNIX 시스템 인 경우 이름 바꾸기 (또는 symlink 업데이트 등) 중에 Apache를 보류시킬 수 있습니다.

killall -STOP httpd  # Pause all httpd processes
mv public_html public_html_orig
mv public_html_new public_html
killall -CONT httpd  # Resume all httpd processes

이렇게하면 이름을 바꾸는 동안 Apache가 새 요청을 수락하지 못하게됩니다. 심볼릭 링크 또는 다른 접근 방식을 선호하는 경우 동일한 아이디어를 사용할 수 있습니다.

killall -STOP httpd  # Pause all httpd processes
rm /var/www/html
ln -s /var/www/version/03 /var/www/html
killall -CONT httpd  # Resume all httpd processes

보류중인 연결 또는 패킷은 OS에서 대기합니다. 사용량이 많은 사이트의 경우 httpd 작업자 유형에 적합한 경우 ListenBacklog 조정을 고려하고 TCP 청취 백 로그와 관련된 OS 설정을 확인하십시오.

httpd.conf에서 DocumentRoot를 변경하고 정상적으로 다시 시작 ( apachectl graceful) 할 수도 있습니다 . 여기서 Directory구성 을 업데이트해야하므로 오류의 위험이 커집니다 .


일시 중지 세션에도 사이트가 계속 실행됩니까?
nicoX

4
Apache에 CPU 시간 제공을 중지합니다. Apache가 일시 중지 된 동안 브라우저에서 사이트에 액세스하려고하면 Apache가 다시 시작될 때까지 (또는 Apache가 시간 초과 기간보다 오래 일시 중지 된 경우 브라우저 시간이 초과 될 때까지) 브라우저는 연결을 대기합니다. 누군가 파일을 다운로드하는 중이라면 Apache는 CPU 시간이 걸리지 않기 때문에 일시 중지 된 동안 데이터 전송을 중지합니다. 다시 말하지만 전송 시간이 초과 될 정도로 Apache가 오랫동안 중지 된 경우에만 문제가 발생합니다.
GargantuChet 1

5
다시 말하면 Apache가 일시 중지 된 동안 사이트가 응답하지 않지만 보류중인 작업은 다시 시작되면 완료됩니다. 사용자는 "연결 거부"를받지 않으며 다운로드는 중단되지 않지만 Apache가 재개 된 후에 만 ​​작업이 계속됩니다. 이렇게하면 기존 트랜잭션이 완료 될 수 있지만 새 요청은 새 컨텐츠가 이동 된 후에 만 ​​처리됩니다.
GargantuChet

1
트래픽이 많은 웹 사이트에서는 Apache 서비스를 매우 쉽게 중단시킬 수 있습니다. (200) RQ / s의 아주 쉽게 (이동 시간이 걸릴 경우) 빨리 이동 한 후 것 '잠금 해제'아파치 프로세스로로 연결 풀을 쓰레기 것
CloudWeavers

1
트래픽이 많은 사이트에서는 Apache가 재개 될 때 완료해야하는 많은 기내 요청이 있습니다. 이것은 새로운 요청 처리를 비틀어 놓을 것입니다. 또한 아파치 설정 (최대 스레드 / 서버 / 클라이언트 수)을 합리적으로 만들고 TCP 백 로그를 적절히 조정하는 것도 좋은 주장입니다. 서비스를 "킬링 (killing)"한다는 의미에 대해 혼란 스러울 수 있습니다. Apache는 매우 조정 가능합니다.
GargantuChet 2

32

가장 빠르고 쉬운 방법은 다음과 같은 버전 디렉토리를 사용하는 것입니다.

/var/www/version/01
/var/www/version/02

현재 심볼릭 링크를 html_root로 사용하십시오.

/var/www/html -> /var/www/version/02

이 기술 은 브랜치 및 태그를 체크 아웃하고 심볼릭 링크를 변경하고 Apache를 다시로드 할 수 있으므로 개정 제어 시스템 (svn, git, mercurial 등)에 완벽하게 통합됩니다 . 가동 중지 시간은 최소한 이 기술을 사용하고는 있습니다 매우 쉽게 롤백 .

또한 RPM 패키지 또는 구성 변경 관리 (chef, puppet 등) 인프라와 같은보다 복잡한 배포 시스템과 잘 통합됩니다.


4
가장 간단한 해결책은 항상 최고입니다 ... :-) 물론, FollowSymlinks와 설정에서 그러한 아파치 플래그가 필요할 수 있습니다.
peterh는 분석 재개 모니카 말한다

@PeterHorvath의 말에 특별한주의를 기울이십시오. 심볼릭 링크 된 DocumentRoots로 작업 할 때 Apache는 매우 심술 g을 수 있습니다. 주의해서 테스트하십시오!
mhutter

감사합니다 @mhutter :-) 정말 문제가 어떤 것이 아파치에 FollowSymLinks를 수 있도록하는 보안 문제를 일으킬 수 있다는 것입니다 ...
peterh는 분석 재개 모니카 말한다

심볼릭 링크를 업데이트하는 것은 원 자성 작업이 아닙니다. ln -snf원래 심볼릭 링크를 클로버하는 것과 같은 것을 사용하더라도 기본 작업은 unlinksymlink입니다. 업데이트하는 동안 사용자가 404를 얻을 가능성이 있습니다. 이것은 파일 디렉토리를 넘지 않는다고 가정 할 때 원래 디렉토리의 이름을 바꾸고 새 디렉토리의 이름을 바꾸는 것보다 낫지 않습니다. 이 문제를 해결하는 옆에 확인 표시가있는 위의 답변을 참조하십시오.
GargantuChet

14

Apache를 종료하지 않고 디렉토리 이름을 바꾸면 작동합니다. 창을 크게 단축시킵니다. mv public_html public_html_old && mv public_html_new public_html순식간에 끝나야합니다.

몇 가지 단점은이 접근 방식이 404여전히 창 중에 발생하는 요청을 처리한다는 것입니다. 그리고 public_html_new디렉토리 없이 위의 명령을 실행 하면 실패하고 404모든 요청을 제공하는 사이트를 남겨 둡니다 .

디렉토리를 원자 적으로 사용하는 것은 지원되지 않습니다. 그러나 심볼릭 링크로 할 수 있습니다. 라는 이름의 디렉토리를 갖는 대신 public_html, 이름이 지정된 디렉토리 public_html.version-numberpublic_html해당 디렉토리를 가리키는 심볼릭 링크가 있어야합니다. 이제라는 디렉토리 public_html.new-version-number와이라는 새 심볼릭 링크를 만들 수 있습니다 public_html.new.

그럼 당신은 이름을 바꿀 수 있습니다 public_html.newpublic_html원자 적으로 전환 할 수 있습니다. 공지 사항 mv"너무 지능"입니다 그 이름 변경을 수행 할 수 있지만 사용하여 수행 할 수 os.rename파이썬 또는 호출 다른 어떤에서 rename스마트려고 노력하지 않고 시스템 호출을.

데이터베이스와 함께 수행 할 작업은 사용중인 데이터베이스 및 사용중인 데이터베이스에 따라 다릅니다. 질문의 해당 부분에 대한 올바른 답변을 제공하기 전에 데이터베이스에 대한 자세한 정보를 제공해야합니다.


1
데비안 시스템 에는 심볼릭 링크를 따라 가지 못하게 mv하는 -T옵션이 있습니다. 이것은 원자의 이름을 변경하게됩니다 public_html.new걸쳐 public_html모두 소프트 링크입니다 가정.
GargantuChet

11

Symlinks와 mv는 당신의 친구이지만, 새 버전을 배포하는 동안 최종 사용자가 오류 페이지를 얻는 것을 피하려면 최소한 2 개의 백엔드 서버 앞에 리버스 프록시 또는로드 밸런서가 있어야합니다 (아파치) 귀하의 경우).

배포하는 동안 한 번에 하나의 백엔드를 중지하고 새 코드를 배포하고 다시 시작한 다음 나머지 백엔드에서 반복하면됩니다.

최종 사용자는 항상 프록시에 의해 올바른 백엔드로 연결됩니다.


4
나는 당신이 이미 게시 한 것을 보았을 때이 답변을 연구하고있었습니다. 밸런서 + 2 서버는 프로세스를 보이지 않게하고 불량 업그레이드로부터 쉽게 복구 할 수 있도록합니다.
Bart Silverstrim

9

프로덕션 시스템에서 정기적으로 변경 사항을 적용하는 경우 구조화 된 수명주기를 처리합니다. 모범 사례는 Capistrano http://capistranorb.com/ 입니다. 여러 플랫폼 및 구성에서 하나 이상의 서버에 소프트웨어를 배포하기위한 오픈 소스 솔루션입니다.

마젠 토의 경우 플러그인도 있습니다 : https://github.com/augustash/capistrano-ash/wiki/Magento-Example

단일 서버 및 거의 완벽한 전환을 위해서는 심볼릭 링크를 사용하는 것이 좋습니다.


4

내가하는 방법은 로컬 dev 환경에서 Github와 같은 온라인 Git 저장소로 변경 사항을 커밋하는 것입니다. 내 프로덕션 환경은 원격 저장소에서 실행되므로 서버에 ssh git pull하고 최신 변경 사항을 적용하기 위해 실행 하면됩니다. 웹 서버를 중지 할 필요가 없습니다.

프로젝트에 설정 및 / 또는 컨텐츠가 로컬 버전 (예 : 구성 파일 및 미디어 업로드)과 다른 파일이있는 경우 환경 변수를 사용하거나 파일에 이러한 파일 / 디렉토리를 추가 .gitignore하여 리포지토리와의 동기화를 방지 할 수 있습니다.


3

나의 첫번째 아이디어는 :

# deploy into public_html_new, and then:
rsync -vaH --delete public_html_new/ public_html/

좋은 해결책은 rsync를 사용하는 것입니다. 실제로 변경된 파일 만 변경했습니다. 마지막에 슬래시와 경로가 중요하다는 점에 유의하십시오.

일반적으로 아파치는 다시 시작할 필요가 없으며 Java 세계가 아닙니다. 요청에 따라 모든 PHP 파일의 변경을 확인하고 변경 사항을 자동으로 다시 읽고 토큰 화합니다.

Git pull은 비슷하지만 효율적 이었지만 스크립트하기가 조금 더 어려웠습니다. 물론 다양한 병합 / 변경 감지 가능성을 가능하게했습니다.

이 솔루션은 실제로 주요 변경 사항이없는 경우에만 완벽하게 작동합니다. 배포에 큰 변경 사항이있는 경우 코드가 부분적으로 변경 될 때 무시할 수있는 시간 간격이 없기 때문에 약간의 위험을 막을 수 없습니다 부분적으로는 아닙니다.

큰 변화가 있다면, 내 제안은 초기 해결책이었습니다 (두 개의 이름 바꾸기).


다음은 약간 하드 코어이지만 100 % 원자 솔루션입니다.

(1) magento가 발생하는 일부 파일 시스템을 대체 마운트하십시오.

mount /dev/sdXY /mnt/tmp

(2) --bindpublic_html_new를 public_html에 마운트하십시오.

mount --bind /path/to/public_html_new /path/to/public_html

이 시점에서 아파치에 새로운 배포가 표시됩니다. 404의 변경은 불가능합니다.

(3) rsync를 가진 synhcronistation을 수행 하지만 ) 대체에 마운트 지점 :

rsync -vaH --delete /mnt/tmp/path/to/public_html_new/ /mnt/tmp/path/to/public_html/

(4) 바인드 마운트 제거

umount /path/to/public_html

이 명령은 public_html을 삭제하고 public_html_new를 배치합니까?
nicoX

@nicoX 아니요, 변경 사항 복사 합니다 .
peterh는 분석 재개 모니카 말한다

@nicoX 디렉토리 구조 를 모두 거치며 차이 (새 파일, 수정 된 파일, 삭제 된 파일)를 찾으면 필요에 따라 첫 번째 디렉토리와 일치하도록 두 번째 디렉토리를 수정합니다. public_html을 삭제 한 다음 public_html_new를 그 자리로 옮겼 지만 일시적인 404 문제는 발생하지 않았습니다.
peterh는 모니카 복구

1
아니요, 이것은 좋은 생각이 아닙니다. 변경 사항에 따라 코드 public_html가 일치하지 않는 짧은 시간 이있을 수 있으며이 기회를 원하지 않습니다.
Sven

@SvW 당신은 ​​옳습니다. 사소한 변경 사항이있는 경우에만 제 생각은 괜찮습니다. 이에 따라 답변을 확장했습니다.
peterh는 분석 재개 모니카 말한다

1

http 서버가 계속 실행되는 동안 http_public간단 mv하거나 ln -s명령 또는 이와 동등한 방법으로 폴더를 이동 / 교체 할 수 있습니다 . 가동 중지 시간을 크게 줄이기 위해 일부 스크립팅을 수행 할 수 있지만 프로세스를 자동화하는 경우 스크립트에서 명령의 리턴 코드를주의 깊게 확인하십시오.

즉, 다운 타임을 달성하지 않으려면 애플리케이션 도이를 지원해야합니다. 대부분의 응용 프로그램은 지속성을 위해 데이터베이스를 사용합니다. 응용 프로그램의 버전 N이 데이터 모델의 버전 N + 1 (또는 그 반대)과 충돌하면 개발 팀에서 예측하지 않으면 문제가 발생할 수 있습니다.

경험상 업그레이드를 통해 이러한 일관성을 유지하는 것은 대부분의 응용 프로그램에 제공되지 않습니다. 다운 타임에도 불구하고 적절한 종료는 일관성 문제를 피하는 좋은 방법입니다.

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