티스토리 뷰

spring boot 2.4 버전부터 애플리케이션 설정 파일( application.properties, application.yml, application.yaml ) 에 대한 구동방식이 변경됐다. 변경된 이유는 k8s 볼륨 마운트 구성때문이라고 하는데 이것에 대해선 논하지 않는다.

 

설정파일에 대해 어떤것들이 변경됐고, 어떻게 마이그레이션해야하는지 알아보자.

 

# 설정이 단순한 경우

애플리케이션 설정파일을 멀티 모듈로 구성하거나 profile 별로 분리해놓지 않았다면 크게 신경 쓸 필요 없이 그대로 구동하면 된다.

 

# 설정이 분리되어 있는 경우

엔터프라이즈 환경에서 규모있는 애플리케이션을 구성한다면 위처럼 설정 파일이 단일로 있지는 않을 것이다. 멀티모듈로 구성되어있다면 애플리케이션 설정 파일에서 추가적인 profile 을 넣어주는 구문이 있을 수 있는데, 아래처럼 애플리케이션 구동시 아래와 같은 워닝 로그가 찍힌다면 마이그레이션이 필요하다.

WARN [org.springframework.boot.context.config.ConfigDataEnvironment:logTo:258] Property 'spring.profiles' imported from location 'class path resource [application.yml]' is invalid and should be replaced with 'spring.config.activate.on-profile' [origin: class path resource [application.yml] - 2:18]

 

1. 레거시 구동방식 유지

가장 간단한 해결법이다. 설정 파일에 아래 설정을 추가해주면 된다.

spring.config.use-legacy-processing=true

 

2. 마이그레이션

기존에 --- 구분자를 사용해서 profile 별 설정을 분리해놓았다면 아래처럼 해당 profile 을 명시했을 것이다.

spring:
  profiles: "profile"

사실 위에서 확인해본 에러메세지가 매우 친절한데, spring.profile 을 spring.config.activate.on-profile 로 변경해주어야 한다.

spring:
  config:
    activate:
      on-profile: "profile"

profile 별로 설정 파일을 작성했고, 추가적인 profile 을 주입했다면 이런식으로 설정을 작성했을 것이다.

spring:
  config:
    activate:
      on-profile: "profile"
  profiles:
    include: "extra1,extra2"

하지만 위 설정은 작동하지 않는다. 2.4 주요 변경사항으로 include 는 특정 profile 이 적용된 곳에서는 사용할 수 없다. 때문에 on-profile 과 include 가 공존할 수 없다. 다음과 같이 사용하면 사용 할 수 있다.

spring:
  profiles:
    include: "extra"
---
spring:
  config:
    activate:
      on-profile: "profile"

실제로 위 구성으로 사용하다보니 이슈가 하나 있었다. 위와 같은 구성에서는 on-profile 과 무관하게 include 가 되게되는데, profile 별로 include 가 달라야하는 필요성이 있었다. 마찬가지로 2.4 에 추가된 스펙인 spring.profiles.group 속성을 사용해 문제를 해결했다.

spring:
  profiles:
    group:
      "profile1": "extra1,extra2"
      "profile2": "extra3,extra4"
---
spring:
  config:
    activate:
      on-profile: "profile1"
---
spring:
  config:
    activate:
      on-profile: "profile2"
---
spring:
  config:
    activate:
      on-profile: "extra1"
---
spring:
  config:
    activate:
      on-profile: "extra3"

spring.profiles.group 속성은 include 와 마찬가지로 spring.config.activate.on-profile 이 있는 상태에서는 사용할 수 없다.

 

3. 그 외

마이그레이션하면서 겪었던 문제지만 마이그레이션 문서에서는 언급되지 않은 문제가 있다. 기존에 spring boot 에서는 profile 을 넣어주지않으면 "default" profile 로 설정 파일을 읽었었는데 2.4 에서 이 기능이 사라졌다. 그래서 profile 이 필요하다면 꼭 넣어줘야한다. 이 기능이 버그인지는 아직 잘 알아보진 않았지만 default 를 이용하고있었다면 이 부분을 유의해서 진행하자.

 

# 2021.04.23 추가

위에 "default" profile 이슈에 대해 적었었는데 내가 2.4 스펙에 대한 이해도가 낮은 상태였단걸 알게됐다. profile 을 주입하지 않은 상태로 애플리케이션 구동시 "default" 로 동작하는 것에는 문제가 없다. 실제 내가 사용하던 환경을 간단히 표현하면 아래와 같다.

// application-default.yml
spring:
  profiles:
    include: "local"
// application.yml
spring:
  profiles:
    include: "extra1" // "extra1" 은 다른 곳에서 사용
---
spring.profiles: "local"

이런 구성에서 profile 없이 애플리케이션을 구동할 경우 가장 먼저 application-default.yml 을 읽게되고, 여기서 "local" 을 주입한다. 그 다음 application.yml 을 읽으면서 "extra1" 을 주입하고, 그 아래 spring.profiles: "local" 을 읽게된다.

 

위 환경에서 2.4 로 올린 후 application.yml 을 수정했다. application-default.yml 은 변동사항이 없다.

// application.yml
spring:
  profiles:
    include: "extra1" // "extra1" 은 다른 곳에서 사용
---
spring:
  config:
    activate:
      on-profile: "local"

마찬가지로 profile 을 넣지않고 애플리케이션을 구동시, application.yml 을 읽어들이면서 "extra1" 이 주입된다. 그럼 profile 이 추가됐기때문에 "default" 로 동작하지않게 된다. 그러면서 자연스럽게 application-default.yml 을 읽지않고, "local" 을 주입받지 않으므로 "local" 설정이 완료되지 않는다.

 

이전에 default 를 읽지않는 것 같다. 라고 말한 이유는 위 상황으로 인한 것이었다. 그리고 application-default.yml 을 실제로 읽게된다하더라도 문제가 있는데 application-default.yml 처럼 profile 이 명시된 파일에서는 어차피 include 를 할 수 없다. 위와 같은 상황에서 내가 해결한 법은 일단 application-default.yml 을 지우고 application.yml 을 아래와 같이 수정했다.

// application.yml
spring:
  profiles:
    group
      "default": "local, extra1" // "extra1" 은 다른 곳에서 사용
---
spring:
  config:
    activate:
      on-profile: "local"

수정 후 기존에 동작하던대로 동작함을 확인했다.

 

# Bug

의도치않게 configuration 설정을 계속 들여다보다보니 이런저런 테스트들을 해봤는데 그러다가 버그를 하나 확인했다.

spring:
  config:
    activate:
      on-profile: "profile"
  profiles:
    include: "extra"

위에서 얘기한대로 위처럼 profile 이 명시된 문서에서 include 를 하면 동작하지 않는다. 실제로 글 작성시점 가장 최신버전인 2.4.5 에서 위 구성으로 실행할 경우 InactiveConfigDataAccessException 이 발생하게 된다. 하지만 아래 구성은 문제없이 잘 동작한다.

spring:
  config:
    activate:
      on-profile: "profile"
  profiles:
    include: 
      - "extra"

예외가 발생하지 않을 뿐 아니라 우리가 기대한대로 "profile" 과 "extra" 가 모두 설정되게된다.

 

이건 버그라고 판단하고 spring-boot 에 PR 을 제기한 상태이며, 답변을 보니 머지가 될 것 같다. 혹시 list 형태로 넣는 꼼수(?)로 마이그레이션을 했다면 차후 버전에서는 동작하지않을 가능성이 크므로 변경하도록 하자.

 

github.com/spring-projects/spring-boot/pull/26205

 

Use of spring.profiles.include in a profile-specific document is not detected when it's configured as a YAML list by LichKing-le

bug fix #26204 . The below case throw InactiveConfigDataAccessException spring: config: activate: on-profile: local profiles: include: - kakaopay1 - kakaopay2

github.com

 

댓글
댓글쓰기 폼