참고 : https://jojoldu.tistory.com/267?category=635883
https://velog.io/@swchoi0329/NGINX-무중단-배포
import lombok.RequiredArgsConstructor;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
@RestController
@RequiredArgsConstructor
public class ProfileController {
private final Environment env;
//현재 어떤 포트로 돌아가는지 확인용. set1 = 8081, set2 = 8082
@GetMapping("/profile")
public String profile() {
//현재 동작중인 프로파일의 이름을 반환
return Arrays.stream(env.getActiveProfiles()).findFirst().orElse("");
}
//무중단배포 테스트를 위한 version 확인용. 새로고침하면 return 값이 자동으로 바뀌는지
@GetMapping("/version")
public String checkVersion() {
return "ver2";
}
}
application.properties에 profile 추가해보기spring.profiles.active=local
localhost에서 구동 후, "/profile" API를 실행시키면 아래와 같이 나온다 WebSecurityConfig에 URI 권한 설정해주기//nginx관련
.antMatchers("/profile").permitAll()
.antMatchers("/actuator/**").permitAll()
.antMatchers("/health").permitAll()
.antMatchers("/version").permitAll()
---
spring:
config:
activate:
on-profile: set1
datasource:
url: jdbc:mysql://joopging-database-1.cjamvr086z6d.ap-northeast-2.rds.amazonaws.com:3306/Joopging_Database_1
username: admin
password: joopging1029
jpa:
hibernate:
ddl-auto: update
jackson:
serialization:
fail-on-empty-beans: false
jwt:
token:
key: skldjficmnwl123kclknmcnfklsdkskmxxfofohue;
server:
port: 8081
---
spring:
config:
activate:
on-profile: set2
datasource:
url: jdbc:mysql://joopging-database-1.cjamvr086z6d.ap-northeast-2.rds.amazonaws.com:3306/Joopging_Database_1
username: admin
password: joopging1029
jpa:
hibernate:
ddl-auto: update
jackson:
serialization:
fail-on-empty-beans: false
jwt:
token:
key: skldjficmnwl123kclknmcnfklsdkskmxxfofohue;
server:
port: 8082
스프링 프로젝트의 Build파일을 app폴더에 옮겨주기 명령어를 통해 jar를 실행시켜준다. 이때 뒤에 특정 port로 실행시키기 위한 명령어가 따라 붙는다 nohup java -jar Joopging-0.0.1-SNAPSHOT.jar --spring.config.location=file:config/prod-application.yaml --spring.profiles.active=set1 &
# 업데이트 해주기
sudo apt-get update
# 자바 설치
sudo apt-get install openjdk-8-jdk
# 자바 버전 확인
java -version
그다음 nginx를 설치 및 실행한다sudo apt-get install nginx
sudo service nginx start
sudo service nginx status
nginx는 80번 포트로 구동되기 때문에 ec2에서 80포트를 열어준다 ec2 서버에 접속시 아래처럼 뜨면 성공. sudo vim /etc/nginx/sites-enabled/default
아래의 명령어 두개를 추가해주는데include /etc/nginx/conf.d/service-url.inc;
proxy_pass $service_url;
이 위치에 추가해준다 그리고 etc/nginx/conf.d 디렉터리로 이동해서 service-url.inc 파일을 생성해준다sudo vim service-url.inc
파일생성 후 내용을 아래처럼 입력 후 저장한다set $service_url http://127.0.0.1:8081;
방금의 설정들이 바로 80포트로 온 요청들을 nginx가 8081포트로 보내주는 설정을 한것이다. 이제 nginx를 재시작해준 후, 다시 브라우저에서 ec2로 들어가서 profile uri 요청을 보내면 아래처럼 잘 나온다. (원래는 set1이 나와야함. 나중에 찍은거라 set2가 돌아가는중이다) sudo vim deploy.sh
만든 후, 아래의 내용을 입력해주고 저장한다#!/bin/bash
echo "> 현재 구동중인 profile 확인"
CURRENT_PROFILE=$(curl -s http://localhost/profile)
echo "> $CURRENT_PROFILE"
if [ $CURRENT_PROFILE == set1 ]
then
IDLE_PROFILE=set2
IDLE_PORT=8082
elif [ $CURRENT_PROFILE == set2 ]
then
IDLE_PROFILE=set1
IDLE_PORT=8081
else
echo "> 일치하는 Profile이 없습니다. Profile: $CURRENT_PROFILE"
echo "> set1을 할당합니다. IDLE_PROFILE: set1"
IDLE_PROFILE=set1
IDLE_PORT=8081
fi
echo "> $IDLE_PROFILE 배포"
sudo fuser -k -n tcp $IDLE_PORT
sudo nohup java -jar /home/ubuntu/app/Joopging-0.0.1-SNAPSHOT.jar --spring.config.location=file:/home/ubuntu/app/config/prod-application.yaml --spring.profiles.active=$IDLE_PROFILE &
echo "> $IDLE_PROFILE 10초 후 Health check 시작"
echo "> curl -s http://localhost:$IDLE_PORT/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
/home/ubuntu/app/switch.sh
현재 8081로 포트가 돌아간다면 8082포트를 IDLE_PORT로 설정 후, 기존 포트는 중단한다. 그리고 새로운 IDLE_PORT를 사용해서 jar를 배포해주겠다는 명령어들이다. 여기서 health check를 실행하는데 이를 위해서 인텔리제이 build.gradle에 다음 라이브러리를 추가해야 한다implementation 'org.springframework.boot:spring-boot-starter-actuator'
전환 스크립트 만들어주기 전환 스크립트는 nginx가 기존에 구동되던 8081에서 8082를 가리키도록 바꿔주는 스크립트이다 위와 같이 app 디렉터리 안에 switch.sh 파일을 생성해준다 그후, 아래와 같이 작성한다#!/bin/bash
echo "> 현재 구동중인 Port 확인"
CURRENT_PROFILE=$(curl -s http://localhost/profile)
if [ $CURRENT_PROFILE == set1 ]
then
IDLE_PORT=8082
elif [ $CURRENT_PROFILE == set2 ]
then
IDLE_PORT=8081
else
echo "> 일치하는 Profile이 없습니다. Profile:$CURRENT_PROFILE"
echo "> 8081을 할당합니다."
IDLE_PORT=8081
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
쉘 권한 부여하기 방금 만든 2개의 쉘에 실행권한을 부여해준다sudo chmod +x deploy.sh
sudo chmod +x switch.sh
이제 deploy.sh 파일을 실행시키면 스크립트가 실행되면서 배포된 port가 바뀐 것을 알 수있다 이제 다시 브라우저에서 ip주소에 접근해보면, profile api의 결과가 바뀐 것을 알 수있다.