본문 바로가기

항해99/스터디

[스터디] 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - Nginx 무중단 배포

무중단 배포?

 

CI / CD만 적용한다면 배포단계에서 애플리케이션이 종료된다는 문제가 있다.

실제 서비스에서 사용자가 서비스를 이용하던 중 갑작스럽게 서비스가 중단된다면 사용자 경험 측면에서 부정적일 것이다.

이 부분의 개선을 위해 무중단 배포를 진행하며, 무중단 배포는 말 그대로 서버를 중단 없이 배포하는 것이다.

Nginx를 선택하는 이유?

 

무중단 배포를 구현하는 방식은 AWS의 ELB, 쿠버네티스, Nginx 등 여러가지가 존재한다.

AWS의 서비스를 이용해 무중단 배포를 하는 건 프리티어 계정을 사용하는 대다수의 개발자들에서 부담스러울 수도 있을 것 같다.

과금이 발생해서 여러 리소스를 삭제해야하는데, 그 과정도 번거롭고 삭제해야하는 항목들이 많아 놓치는 부분이 발생한다면 나도 모르게 추가 과금이 발생할 수 있다. 그리고 쿠버네티스를 사용하기에는 러닝커브도 높고 시간도 많지 않기 때문에 Nginx가 가장 적합할 것 같다는 생각이 들었다.

 

  1. Nginx는 강력한 로드 밸런싱 기능을 제공해서 수신 트래픽을 여러 백엔드 서버에 분산시킬 수 있다. 세션의 지속성, 상태 확인, 동적 재구성과 같은 기능을 통해 Nginx는 애플리케이션의 가용성을 높이고 확장성을 보장합니다.
  2. Nginx는 동시 연결을 처리하고 정적 콘텐츠를 제공하는 데 있어 높은 성능과 효율성으로 유명하다. 이벤트 기반 아키텍처와 비동기 처리를 통해 Nginx는 최소한의 리소스 활용으로 수 많은 동시 요청을 처리할 수 있다.

 

Nginx를 이용한 배포 원리

 

Nginx를 이용하기 위해서는 전제조건이 필요하다.

  • 동일한 애플리케이션이 배포된 여러 백엔드 서버
  • Nginx는 로드 밸런서 역할을 하기 위해 별도의 서버에 설치된다
  • Nginx 구성에 대한 기본 이해

Nginx는 외부의 요청을 받아 서버로 요청을 전달하는 리버스 프록시 기능이 있다.

즉,  클라이언트는 nginx의 주소로 접속하고 nignx는 웹서버에 클라이언트의 요청을 전달하는

"클라이언트 -> nginx -> 웹서버" 구조가 된다.

 

출처 : jojoldu/springboot-webservice 

 

하나의 EC2 서버에 Nginx 1대와 스프링부트 jar를 2대를 사용하는 방식이다.

  1. 클라이언트는 Nginx 서비스 주소로 접속 (80 포트 or 443 포트)
  2. Nginx는 클라이언트 요청을 받아 현재 연결된 스프링 부트 1로 요청을 전달한다.
    연결되지 않은 스프링 부트2는 전달받지 못한다.
  3. 1.1 버전으로 신규 배포가 필요하면 Nginx 와 연결되지 않은 스프링 부트2로 배포된다. Nginx 는 스프링 부트 1을 바라보고 있으므로 배포하는 동안 서비스가 중단되지 않는다.
  4. 배포 이후 스프링 부트 2가 정상적으로 구동되는지 확인하고, nginx reload 명령어(0.1초 이내)를 통해 스프링 부트 2를 바라보도록 한다.

Nginx는 서버 내부에서 신규 트래픽을 어디로 라우팅할 것인지 정해 요청을 전달하므로 한대의 서버에서 2개의 애플리케이션을 무중단 배포 할 수 있다.

 

Nginx를 사용하여 무중단 배포를 구성하는 방법

 

업스트림 서버 정의

Nginx 구성 파일(nginx.conf) 열고 http 블록 아래에 업스트림 서버를 정의한다.

백엔드 서버의 IP 주소 또는 호스트 이름을 지정하고 필요한 경우 가중치도 할당해준다.

http {
    upstream backend {
        server backend1.example.com weight=3;
        server backend2.example.com;
        server backend3.example.com;
    }
}

 

 

로드 밸런서 구성

'server' 블록 내에서 위치 블록을 정의하고, 'proxy_pass' 지시어를 사용하여 업스트림 서버에 요청을 프록시함으로써

Nginx 로드 밸런서 역할을 하도록 구성한다.

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;
    }
}

 

로드 밸런싱 알고리즘

선택적으로 사용할 로드 밸런싱 알고리즘을 지정한다.

Nginx round-robin, least_conn, ip_hash 같은 다양한 알고리즘을 지원해주기 때문에 요구 사항에 따라 적절한 알고리즘을 선택한다.

Copy codeupstream backend 
{ 
least_conn; server backend1.example.com; 
server backend2.example.com; 
server backend3.example.com; 
}

 

 

테스트 구성

구성 변경 사항을 적용하기 전에 Nginx 구성을 테스트하여 구문 오류가 없는지 확인을 한다.

Copy codenginx -t

 

Nginx 리로드

구성 테스트가 성공하면 Nginx 다시 로드하여 변경 사항을 적용한다.

Copy codenginx -s reload