티스토리 뷰

서비스 단절 없이 New version 의 nginx binary 를 Upgrade 하는 방법에 대해 작성한 문서입니다.

이번에 nginx 를 사용할 일이 있어, nginx all-in-one static binary 로 빌드를 하고 서버에 배포를 하게 되었습니다. 그런데 생각해보니, 우리는 무정지 서비스 배포를 해야하는데, nginx 는 이게 가능한지 찾아보게되었습니다.

공식 사이트에 친절하게 설명해 놓았네요. 영어 무능력자 구글 번역기와 직접 사용해보면서 확인해본 내용을 정리합니다.

NOTE! 해당 문서의 내용은 직접 컴파일한 nginx binary 를 교체하여 무정지 서비스 배포하는 내용입니다.
확인해보지는 않았지만, RPM 을 사용할 경우 자동으로 되는것으로 알고있습니다.

Nginx 무정지 서비스 배포하기.

요약:

  1. old version nginx binary file 을 new version nginx binary file 로 교체한다.
  2. old version nginx master process 에게 USR2 신호를 전송합니다.
  3. old version nginx master process 에게 WINCH 신호를 전송합니다.
  4. old version nginx master process 에게 QUIT 신호를 전송합니다.

명령어:

$ kill -USR2 $(cat nginx.pid)

$ kill -WINCH $(cat nginx.pid.oldbin)

$ kill -QUIT $(cat nginx.pid.oldbin)

 

설명:

 

  1. 바이너리 교체:

nginx 는 실행되면 memory 에 Main process 와 Child process 가 등록되고, 해당 binary 를 참조하지 않습니다. 그냥 교체하면 됩니다.

 

  1. USR2 신호 전송

nginx 는 USR2 신호를 받게 되면 자신의 PID 이름을 nginx.pid 에서 nginx.pid.oldbin 으로 변경합니다.
그리고 자신이 실행된 binary file 을 실행해 프로세스를 띄웁니다.
이렇게 되면 실행되고 있는 메모리에 old version nginx 와 new version nginx 2개가 떠서 서로가 유입되는 요청들은 old version 과 new version 이 함께 처리합니다.

 

  1. WINCH 신호 전송

old version nginx 는 WINCH 신호를 받으면, 자신의 worker process 들을 graceful shutdown 합니다. 시간이 지나면 old version nginx 의 worker process 들이 전부 종료가되고 이 때부터 new version nginx 의 worker process 들이 유입되는 요청들을 처리합니다.

이 때, old version nginx 를 복구할 수 있습니다. 즉, 유입되는 요청들을 처리하는 new version nginx 에 문제가 있다면요.

복구 되는 방법은 밑에 다시 정리하겠습니다.

 

  1. QUIT 신호 전송

old version nginx 는 QUIT 신호를 받으면 자신의 master process 를 종료함으로써 완전히 메모리에서 사라지게 됩니다. 이로써 완벽히 무정지 서비스 배포가 완료됩니다.

NOTE! old version nginx 는 QUIT 신호를 받으면 자신의 nginx.pid.oldbin 을 삭제합니다.

Nginx Revert 하기

3번째 작업 후에 상황을 파악한 후 old version nginx 로 복구해야한다면 이 시점에서 할 수 있습니다. 왜냐하면 master process 가 종료되지 않았고, socket 도 닫히지 않았기 때문입니다.

복구 절차:

  1. old version nginx 에게 HUP 신호 전달.
  2. new version nginx 에게 QUIT 신호 전달.
  3. new version nginx 에게 TERM 신호 전달.

만일 TERM 신호를 보냈지만 worker 들이 죽지 않는다면, KILL 신호를 보내 강제로 죽입니다.

  1. nginx.pid.oldbinnginx.pid 로 변경합니다.

참조: https://www.nginx.com/resources/wiki/start/topics/tutorials/commandline/