ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Nginx 무중단 배포
    AWS 2023. 11. 10. 14:46

    참고 : 스프링 부트와 AWS로 혼자 구현하는 웹 서비스

     

     

     

    1. 엔진엑스 설치와 스프링 부트 연동하기

    # 엔진엑스 설치
    sudo yum install nginx
    
    # 엔진엑스 실행
    sudo service nginx start

     

    엔진엑스가 현재 실행 중인 스프링 부트 프로젝트를 바라볼 수 있도록 프록시 설정을 한다.

    sudo vim /etc/nginx/nginx.conf

     

    nginx.conf

    • proxy_pass
      - 엔진엑스로 요청이 오면 http://localhost:8080로 전달합니다.

    • proxy_set_header XXX
      - 실제 요청 데이터를 header의 각 항목에 할당합니다. 
      - 예) proxy_set_header X-Real-IP $remote_addr: Request Header의 X-Real-IP에 요청자의 IP를 저장합니다.
    # 엔진엑스 재시작
    sudo service nginx restart

     

     

    2. 무중단 배포 스크립트 만들기

    profile API 추가

    배포 시에 8081을 쓸지, 8082를 쓸지 판단하는 기준이 되는 API 작성

     

    https://github.com/501501/freelec-springboot2-webservice/commit/f8fbf94d2848e67f5d2897b60ffc02490164df70

     

    feat: 10.3 무중단 배포 스크립트 만들기 · 501501/freelec-springboot2-webservice@f8fbf94

    501501 committed Nov 7, 2023

    github.com

     

    • env.getActiveProfiles()
      - 현재 실행 중인 ActiveProfile을 모두 가져온다.
      - 즉, real, oauth, real-db 등이 활성화되어 있다면(active) 3개가 모두 담겨있다.
      - 여기서 real, real1, real2는 모두 배포에 사용될 profile이라 이 중 하나라도 있으면 그 값을 반환한다.
      - 실제로 이번 무중단 배포에서는 real1과 real2만 사용되지만, step2를 다시 사용해볼 수도 있으니 real도 남겨둔다.

     

    real1, real2 profile 생성

    현재 EC2 환경에서 실행되는 profile은 real밖에 없다.
    해당 profile은 Travis CI 배포 자동화를 위한 profile이니 무중단 배포를 위한 profile 2개(real1, real2)를 src/main/resources 아래에 추가한다.

     

    application-real1.profiles

    server.port=8081
    spring.profiles.include=oauth,real-db
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
    spring.session.store-type=jdbc

     

    application-real2.profiles

    server.port=8082
    spring.profiles.include=oauth,real-db
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
    spring.session.store-type=jdbc

     

    엔진엑스 설정 수정 

    무중단 배포의 핵심은 엔진엑스 설정이다. 

    배포 때마다 엔진엑스의 프록시 설정(스프링 부트로 요청을 흘려보내는)이 순식간에 교체된다.

    여기서 프록시 설정이 교체될 수 있도록 설정을 추가한다.

    # 엔진엑스 설정이 모여있는 /etc/nginx/cof.d/ 에 service-url.inc라는 파일을 하나 생성
    sudo vim /etc/nginx/conf.d/service-url.inc

     

    service-url.inc

    set $service_url http://127.0.0.1:8081;

     

    위 service-url.inc 파일을 엔진엑스가 사용할 수 있게 설정한다.

    sudo vim /etc/nginx/nginx.conf

     

    nginx.conf

     

    배포 스크립트들 작성

    # step2와 중복되지 않기 위해 EC2에 step3 디렉토리 생성
    mkdir ~/app/step3 && mkdir ~/app/step3/zip

     

    appspec.yml

    version: 0.0
    os: linux
    files:
      - source: /
        destination: /home/ec2-user/app/step3/zip/
        overwrite: yes
    
    permissions:
      - object: /
        pattern: "**"
        owner: ec2-user
        group: ec2-user
    
    hooks:
      AfterInstall:
        - location: stop.sh # 엔진엑스와 연결되어 있지 않은 스프링 부트를 종료합니다.
          timeout: 60
          runas: ec2-user
      ApplicationStart:
        - location: start.sh # 엔진엑스와 연결되어 있지 않은 Port로 새 버전의 스프링부트를 시작합니다.
          timeout: 60
          runas: ec2-user
      ValidateService:
        - location: health.sh # 새 스프링 부트가 정상적으로 실행됐는지 확인합니다.
          timeout: 60
          runas: ec2-user

     

    • stop.sh : 기존 엔진엑스에 연결되어 있지 않지만, 실행 중이던 스프링 부트 종료
    • start.sh : 배포할 신규 버전 스프링 부트 프로젝트를 stop.sh로 종료한 'profile'로 실행
    • health.sh : 'start.sh' 로 실행시킨 프로젝트가 정상적으로 실행됐는지 체크
    • switch.sh : 엔진엑스가 바라보는 스프링 부트를 최신 버전으로 변경
    • profile.sh : 앞선 4개 스크립트 파일에서 공용으로 사용할 'profile' 과 포트 체크 로직

    https://github.com/501501/freelec-springboot2-webservice/tree/master/scripts

     

     

    3. 무중단 배포 테스트

    build.gradle

    자동으로 Jar 파일명 버전값이 변경될 수 있도록 설정

    version '1.0.1-SNAPSHOT-'+new Date().format("yyyyMMddHHmmss")

     

    배포가 진행되면 CodeDeploy 로그로 잘 진행되는지 확인

    tail f- /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log

     

    스프링 부트 로그 확인

    vim ~/app/step3/nohup.out

     

    2번 배포를 진행한 뒤 자바 애플리케이션 실행 여부 확인하면 2개의 애플리케이션이 실행되고 있음을 알 수 있다.

    ps -ef | grep java

     

     

    댓글

Designed by Tistory.