[Springboot] nginx 무중단 배포 환경 설정
nginx 설치하는 방법은 nginx 설치법에서 확인할 수 있다.
Spring Profile 설정
프로필 확인
@RestController @RequiredArgsConstructor public class WebRestController { private final Environment env; @GetMapping("/profile") public String getProfile() { return Arrays.stream(env.getActiveProfiles()).findFirst().orElse(""); } }
WebRestController를 통해서 현재 어떤 profile을 사용 중인지 확인할 수 있다.
라이브러리 추가
implementation 'org.springframework.boot:spring-boot-starter-actuator
위 라이브러리를 dependencies 안에 넣어준다.
prod-application.yml 설정
~$ sudo mkdir config ~$ cd config ~$ sudo vim prod-application.yml
jar 배포 파일이 존재하는 곳(프로젝트 폴더 안의 build/libs에 있다)으로 이동해서 config 폴더를 만들어 주고 안에 yml 설정 파일을 만들어준다.
--- # prod1 환경 spring: config: activate: on-profile: prod1 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://주소:3306/스키마?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC&autoReconnect=true username: 아이디 password: 비번 jpa: hibernate: ddl-auto: update generate-ddl: true show-sql: true properties: hibernate: format_sql: true database: mysql database-platform: org.hibernate.dialect.MySQL5InnoDBDialect logging: level: root: info server: port: 8089 --- --- #prod2 환경 spring: config: activate: on-profile: prod2 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://주소:3306/스키마?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC&autoReconnect=true username: 아이디 password: 비번 jpa: hibernate: ddl-auto: update generate-ddl: true show-sql: true properties: hibernate: format_sql: true database: mysql database-platform: org.hibernate.dialect.MySQL5InnoDBDialect logging: level: root: info server: port: 8090
본인의 기존 데이터베이스를 포함한 설정 정보들을 모두 가져와주고, profile 두 개를 각각 8089, 8090포트로 나눠준다.
- 이 경우 ec2에서 8089, 8090포트를 열어줘야 한다.
실행
~$ java -jar 본인jar이름.jar --spring.config.location=file:config/prod-application.yml --spring.profiles.active=prod1
위의 명령어를 실행하면 prod-application.yml의 prod1 profile 설정을 통해서 실행을 시켜 8089 포트로 실행이 된다
"The follwing 1 profile is active: "prod1"이 뜬다면 profile 설정은 성공이다.
Nginx 설정
nginx.conf 수정
~$ sudo vim /etc/nginx/nginx.conf
/etc/nginx/nginx.conf에 들어가 위와 같이 수정~$ sudo service nginx reload
설정 후 nginx을 재시작 해준다.
~$ sudo vim /etc/nginx/conf.d/service-url.inc
service-url.inc을 생성하여 안에 위와 같이 적고 저장한다.
그러면 기본 설정을 prod 1인 8089 포트로 설정해준 것이고, nginx.conf에서 이 주소를 읽어와 전달해준다.
nginx 포트 전달
위의 설정을 마치면 아래와 같이 80포트로 들어오는 요청을 스프링의 8089포트로 전달해준다.
Nginx 재시동 및 전환
이번엔 쉘 스크립트를 사용해서 스프링 서버를 재시동하고 nginx가 해당 스프링 서버를 가리킬 수 있도록 한다.
재시동 쉘 스크립트 작성(deploy.sh)
~$ sudo vim deploy.sh
jar파일이 있는 곳에 deploy.sh를 만들어준다.
#!/bin/bash echo "> 현재 구동중인 profile 확인" CURRENT_PROFILE=$(curl -s http://localhost/profile) echo "> $CURRENT_PROFILE" if [ $CURRENT_PROFILE == prod1 ] then IDLE_PROFILE=prod2 IDLE_PORT=8090 elif [ $CURRENT_PROFILE == prod2 ] then IDLE_PROFILE=prod1 IDLE_PORT=8089 else echo "> 일치하는 Profile이 없습니다. Profile: $CURRENT_PROFILE" echo "> prod1을 할당합니다. IDLE_PROFILE: prod1" IDLE_PROFILE=prod1 IDLE_PORT=8089 fi echo "> $IDLE_PROFILE 배포" sudo fuser -k -n tcp $IDLE_PORT sudo nohup java -jar core-0.0.1-SNAPSHOT.jar --spring.config.location=file:config/prod-application.yml --spring.profiles.active=$IDLE_PROFILE & echo "> $IDLE_PROFILE 10초 후 Health check 시작" echo "> curl -s http://localhost:$IDLE_PORT/actuator/health " sleep 10 for retry_count in {1..10} do response=$(curl -s http://localhost:$IDLE_PORT/actuator/health) up_count=$(echo $response | grep 'UP' | wc -l) if [ $up_count -ge 1 ] then echo "> Health check 성공" break else echo "> Health check의 응답을 알 수 없거나 혹은 status가 UP이 아닙니다." echo "> Health check: ${response}" fi if [ $retry_count -eq 10 ] then echo "> Health check 실패. " echo "> Nginx에 연결하지 않고 배포를 종료합니다." exit 1 fi echo "> Health check 연결 실패. 재시도..." sleep 10 done echo "> 스위칭을 시도합니다..." sleep 10 sh /home/ec2-user/backend-phonedyguard/core/build/libs/switch.sh
jar 파일 이름과, 마지막 줄 switch.sh 파일 위치는 본인에 맞게 바꿔야 한다.
- 3번 라인: 현재 nginx가 가리키는 스프링의 profile을 확인한다.
- 6~19번 라인: 현재 가리키고 있는 CURRENT_PROFILE과 IDLE_PROFILE을 구분한다.
- 21~23번라인
- sudo fuser -k -n tcp $IDLE_PORT: IDLE_PORT로 구동 중인 스프링 서버가 있으면 중단
- sudo nohup java -jar core-0.0.1-SNAPSHOT.jar --spring.config.location=file:config/prod-application.yml --spring.profiles.active=$IDLE_PROFILE &: 스프링 로그는 nohup.out에 기록하며 백그라운드로 IDLE_PROFILE의 스프링 서버 가동(뒤에 &를 붙이지 않으면 다음 명령을 실행하지 않는다.)
- 25~라인
- 일정 시간 후 10번 동안 서버 health check - Actuator 라이브러리 사용
- 실패하면 code 1로 스크립트 종료
- 성공하면 반복문을 빠져나가고 전환 스크립트 실행
전환 쉘 스크립트 작성(switch.sh)
~$ sudo vim swich.sh
마찬가지로 jar 파일 위치에 생성해준다.
#!/bin/bash echo "> 현재 구동중인 Port 확인" CURRENT_PROFILE=$(curl -s http://localhost/profile) if [ $CURRENT_PROFILE == prod1 ] then IDLE_PORT=8090 elif [ $CURRENT_PROFILE == prod2 ] then IDLE_PORT=8089 else echo "> 일치하는 Profile이 없습니다. Profile:$CURRENT_PROFILE" echo "> 8089를 할당합니다." IDLE_PORT=8089 fi PROXY_PORT=$(curl -s http://localhost/profile) echo "> 현재 구동중인 Port: $PROXY_PORT" echo "> 전환할 Port : $IDLE_PORT" echo "> Port 전환" echo "set \$service_url http://127.0.0.1:${IDLE_PORT};" | sudo tee /etc/nginx/conf.d/service-url.inc echo "> Nginx Reload" sudo service nginx reload
- 3~15번 라인: 현재 구동 중인 스프링 프로필을 확인하여 새롭게 가리킬 프로필 셋을 지정한다.
- 22번 라인: /etc/nginx/conf.d/service-url.iinc 파일에 포트 부분을 IDLE_PORT로 바꿔준다.
- 25번 라인: nginx가 새로 업데이트된 service-url.inc 파일의 내용을 리로드하여 재시작한다.
실행
~$ sh deploy.sh
deploy.sh를 실행시켜준다.
개행문자 오류
원인
- 처음에 위와 같은 문제가 발생하길래 원인을 찾아보니 window 환경에서 파일을 생성하여 git에 올리고 그것을 그대로 받아와서 window와 linux 사이의 개행 문자 차이 때문에 발생한 오류였던 것 같다.
해결
ec2에서 직접 타이핑 해서 쓰면 위와 같은 오류가 발생하지 않는다.
prod1 에서 prod2로 전환되며 백그라운드로 Spring jar 파일이 잘 실행되는 것을 확인할 수 있다.
Author And Source
이 문제에 관하여([Springboot] nginx 무중단 배포 환경 설정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jinyeong-afk/Springboot-nginx-무중단-배포-환경-설정저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)