Spring profile별 환경 분리 하기
1. 환경을 분리해야 하는 이유?
실무에서 개발할때는 운영 환경에 테스트를 할수는 없습니다.
테스트시에 혹여나 데이터를 잘못 건드리는 경우는 장애를 초래 할수 있기 때문인데요.
테스트간 별다른 큰 문제가 발생하지 않으면 좋겠지만, 그렇지 않을 확률이 높으니까요.
그래서 테스트시에는 별도로 분리된 환경에서 테스트하는것이 좋습니다.
혹여나 잘못되더라도 운영 환경에는 아무런 영향이 없기 위함입니다.
예를들면 테스트간 사용하는 DB는 개발용도로만 사용하는 DB이면 좋을것입니다.
2. 어떻게 분리된 환경을 사용할까?
스프링에서는 설정된 프로필에 따라 다른 환경에서 구동될수 있도록 하는 기능을 제공하고 있답니다.
예를 들어 개발환경에서 테스트하는 경우 로컬 DB에 접근 하도록 설정하고,
운영 환경에서는 DB 서버에 접근하도록 설정하는것도 가능합니다.
만일 프로필에 따른 환경 분리 기능을 제공하지 않는 다면 어떻게 해야 할까요?
우리는 서로 다른 환경을 구분하기 위한 추가적인 코드를 짜야 할수도 있습니다.
운영환경에서는 MySQL을 사용하고, 개발 환경에서는 로컬 h2를 써야한다고 가정해보겠습니다.
각각의 데이터 베이스는 도커를 통해 실행 시키도록 합니다.
시작/종료를 쉽게 하기 위한것일뿐 꼭 도커 환경에서 학습을 해야하는것은 아닙니다!
앞선 도커에서 MySQL 포스팅을 통해 데이터 베이스 설치가 완료 상태에서 진행합니다.
그럼 어떻게 환경을 구분 할 수 있는지 알아보겠습니다.
3. application.yml를 통한 profile 환경 분리
3.1. 일반적인 application.yml 파일
application.yml 파일을 한번 봐보도록 하겠습니다.
h2를 사용하고 있고, 8080 포트를 사용하는 기본적인 application.yml 파일 입니다.
server:
port: 8080
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:tcp://localhost:1521/test
username: sa
password:
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
show_sql: true
format_sql: true
open-in-view: true
logging:
level:
org.hibernate.type.descriptor.sql: trace
3.2. application.yml 환경별로 생성하고 설정하기
그럼 어떻게 application.yml 파일을 통해 환경을 분리 할 수 있을까요?
다행히 스프링에서는 이런한 기능을 옵션을 통해 제공하고 있습니다.
환경 분리를 위해서는 각자 다른 설정의 파일이 존재해야 겠죠?
프로필별로 사용할 파일을 만들어 보도록 하겠습니다.
이렇게 application-<이름>.yml 파일을 만들어 주도록 합니다.
application.yml은 어떠한 프로필을 사용할것인지 설정하기 위해 사용합니다.
dev는 개발 환경에서 사용할 설정을 해주는 파일 입니다.
prod는 운영 환경에서 사용할 설정을 해주는 파일 입니다.
create는 Jpa 설정에서 ddl-auto 설정이 create로 되어있는 설정입니다.
예제에서 create는 별도로 설명 하지 않도록 하겠습니다.
prod 환경은 앞서 설명한 application.yml 의 기본설정에서 다음이 변경되었습니다.
환경을 분리해야 한다고 하였으니 데이터 베이스를 MySQL로 변경하도록 합니다.
같은 DB의 다른 데이터 베이스를 사용해도 됩나 쉬운 확인을 위해 서로 다른 DB를 사용하겠습니다.
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/study_db?serverTimezone=Asia/Seoul
username: root
password: root1234
3.3. 환경별 프로필명 설정하기
이제 각각의 프로필로 사용할 파일들에 대한 설정은 완료되었습니다.
그럼 이제 각각의 프로필을 어떻게 구분할수 있을까요?
바로 설정 값을 통해 어떠한 프로필로 사용하겠다 라고 스프링에게 알려줄 수 있습니다.
spring:
config:
activate:
on-profile: dev
datasource:
driver-class-name: org.h2.Driver
위의 설정은 이파일을 dev라는 프로필로 사용하겠다고 설정하는 것입니다.
위 설정을 dev와 prod 파일에 추가해주도록 합니다.
3.4. 사용할 프로필 설정하기
그럼 어떻게 dev와 prod를 사용할지 설정할수 있을까요?
크게 두가지 방법이 있습니다.
우선 첫번째 방법은 application.yml 파일에 설정을 추가하는 방법입니다.
spring:
profiles:
active: prod
다음과 같이 말이죠.
위의 설정은 profile을 prod 라는 이름의 프로필을 사용하겠다는 설정입니다.
두번째 방법은 인텔리 제이를 통해 설정하는 방법입니다.
인텔리 제이 상단 메뉴에 Run -> Edit Configurations 설정을 클릭합니다.
그럼 위와 같은 설정 창이 표시됩니다.
저희가 만든 스프링 부트 어플리케이션 설정을 클릭합니다.
Active Profiles에 사용할 프로필의 이름을 입력해줍니다.
인텔리 제이의 설정을 이용하는 경우 별도의 파일에 설정을 해줄 필요가 없습니다.
마지막으로 두개다 설정을 하는 경우 어떻게 될까요?
저도 두가지 설정을 함꼐 설정하는 경우가 궁금하여, 직접 확인 해보았습니다.
저의 예상은 파일의 설정으로 반영될줄 알았는데, 실제로는 인텔리 제이 설정을 따라갔습니다.
혹시라도 두개 모두 설정하는 경우 주의 하시기 바랍니다.
3.5. Default 프로필 설정하기
추가로 다음과 같은 설정을 통해 기본 프로필로 무엇을 사용할지도 설정이 가능합니다.
spring:
profiles:
default: dev
위의 설정은 active된 프로필이 없을때, 기본 프로필로 무엇을 사용할것인가를 설정합니다.
그럼 설정이 제대로 작동하는지 확인 해보도록 하겠습니다.
4. application.yml를 profile 별로 사용해보기
4.1. application.yml 파일 나누는 팁!
프로필 설정이 제대로 작동하는지 확인하기 전에 확인 해야할 내용을 보겠습니다.
application.yml 파일은 분리하여 include 하여 사용하는 기능도 제공하고 있습니다.
따라서 민감한 정보를 가지고 있는 설정은 따로 분리하여 사용하기도 합니다.
그럼 프로필 별로 무엇을 나누어야 하고, 무엇을 공통으로 사용할수 있을까요?
사실 정답은 없습니다. 그래서 개인적으로 사용하는 방법을 공유하려고 합니다.
저같은 경우에는 개발 환경에서 사용하는 인프라와 관련된 정보는 프로필로 나누어 사용합니다.
또한 개발 환경에서는 로그를 좀더 쉽게 보기위해 로깅 설정등을 분리합니다.
그럼 무엇을 공통으로 사용할까요? 예를 들면 Jpa의 설정과 관련된 부분은 공통으로 사용합니다.
Jpa의 설정의 경우 서로 다르게 설정하는 경우 실제 동작에도 영향을 끼치는 경우가 있기 떄문입니다.
4.2. 프로필 설정 테스트 해보기
그럼 설정이 제대로 동작하는지 확인 해도록 할까요?
앞서 설정을 제대로 따라오셨다면 지금 환경은 다음과 같습니다.
dev 프로필은 h2 DB를 prod 프로필은 MySQL의 설정을 가지고 있습니다.
그럼 테스트 스텝은 다음과 같습니다.
- dev 프로필 설정 후 h2 DB에 정상적으로 접속하는지?
- prod 프로필 설정 후 MySQL DB에 정상적으로 접속하는지?
1번을 테스트하기 위해서 MySQL 컨테이너를 종료하도록 하곘습니다.
그다음 스프링 어플리케이션을 실행 합니다.
만일 정상적으로 수행 되었다면 올바르게 설정이 된것입니다.
그럼 이제 h2 DB도 종료해줍니다.
그후 다시 스프링 어플리케이션을 실행합니다.
이번에는 당연히 DB에 접근하지 못하니 구동에 실패 할것입니다.
2번을 테스트 하도록 하겠습니다.
기본 프로필을 prod로 변경하여줍니다.
앞선 테스트를 위해 MySQL을 종료 하였기 떄문에, 역시 구동에 실패 해야합니다.
실패 하였다면, MySQL을 구동하고 스프링 어플리케이션을 다시 실행합니다.
prod 프로필은 MySQL에 접근 하므로, 정상 구동되어야 합니다.
테스트를 마무리하느라 고생하셨습니다!! 그럼 좀더 쉽운 프로필 확인 법을 알려드리겠습니다...?!?!
4.3. 로그를 통해 프로필 확인 하기
프로필 설정을 컨테이너 종료까지 하면서 테스트하였는데, 더 쉬운 방법이 있었다니?
라고 생각하실수도 있겠습니다.
네! 말그대로 스프링 어플리케이션 구동시에 로그를 통해 프로필을 확인 하실수 있습니다.
다음과 같이 말이죠!
그럼 왜 DB 까지 종료해가면서 확인을 한것일까요?
물론 로그를 통해서 손쉽게 확인 할수는 있지만, 보다 확실한 확인을 위해 컨테이너를 종료하여 테스트 하였습니다.
그럼 아까 말씀드린 Default 프로필인 경우에도 로그로 확인 가능할까요?
네! 가능합니다. 스프링에서 친절하게 활성화된 프로필이 없어 기본값으로 사용하는 프로필 까지 알려줍니다.
다음에는 설정 파일과 관련된 심화된 내용을 확인해보도록 하겠습니다!
5. 설정 파일 더보기
5.1. application.yml 파일을 사용하는 이유
스프링에서는 .properties 파일과 .yml 파일 두가지 형태의 설정 파일을 지원합니다.
yml 파일을 사용하는 이유는 properties 파일과는 다르게 계층형 형식을 통해 가독성이 높아집니다.
또한 properties 파일에 비해 반복되는 내용이 적습니다.
또한 List 형태의 데이터도 - 를 통해 쉽게 설정이 가능합니다.
5.2. @Valu 어노테이션
어떠한 값을 코드에서 바로 사용하지 않고 설정 파일에 설정된 값을 사용해야하는 경우도 있습니다.
이런 경우는 코드에 그대로 노출 시키는 경우 문제가 되는 경우에 사용합니다.
만일 aws키 같은 중요한 정보들이 외부에 노출된다면, 엄청난 과금 폭탄을 맞게됩니다.
또한 쉽게 변하거나 변경이 되는 경우가 있는 경우 그값이 코드에 있다면, 변경될떄마다 코드를 변경해야합니다.
하지만 설정 파일에서 값을 가져와 사용한다면, 코드를 변경하지 않고 파일만 변경하여 사용이 가능합니다.
이런 경우 @Value 어노테이션을 통해서 Bean 내부에서 값을 주입 받아 사용하기도 합니다.
@Component
@RequiredArgsConstructor
public class JwtTokenProvider {
private static Logger log = LoggerFactory.getLogger(JwtTokenProvider.class);
@Value("${security.jwt.token.secret-key}")
private String secretKey;
@Value("${security.jwt.token.expire-length:200000}")
private long validityInMilliseconds;
...
}
위의 코드는 jwt 토큰을 생성하는 코드입니다.
jwt토큰 생성에 사용하는 secrete key 같은 예민한 정보는 파일로 설정 후 주입받아 사용합니다.
앞서 말씀드린것과 같이 예민한 정보는 따로 파일로 분리하고, .gitignore 파일에 등록합니다.
이렇게 한다면, 버전 관리 시스템인 git에 해당 정보를 업로드 되지 않습니다.
서비스를 구성하는데 필요로 하는 정보중 민감한 정보들은 다음과 같은 방법으로 외부로 노출되지 않도록 합니다.
추가로 만일 해당 파일에 설정이 없는 경우가 존재할 수 있습니다.
하지만 만일 그 값이 서비스를 운영하는데 반드시 필요한 값인 경우가 있습니다.
그런 경우에는 : 구분자를 사용하여 만일 파일에 해당 설정 값이 없다면 값을 기본값 설정할 수 있습니다.
예제에서 security.jwt.token.expire-length 값이 없는 경우 기본값을 20000으로 설정하겠다는 뜻입니다.
6. 마무리
application.yaml 파일 설정은 프로젝트 초기나 인프라의 변경이 있을때 정도에 변경하곤 합니다.
또한 스프링 프로젝트를 만들면서 가장 먼저 설정하기도 합니다.
포스팅에서는 application.yaml 설정 파일에 대해 알아보고, 프로필에 따라 파일을 분리하는 방법을 배웠습니다.
프로필 분리를 통해 환경에 맞는 설정으로 편리하게 사용할 수 있습니다.
'Spring' 카테고리의 다른 글
[Spring] 의존성 주입(Dependency Injection, DI) 정리 (0) | 2023.08.08 |
---|---|
[Spring] @EnableJpaAuditing 기능 사용해 생성/수정 시간 등록하기 (0) | 2023.06.29 |
댓글