Spring profile 분리하여 환경에 따라 다른 설정 사용하기 (with Embedded DB)

유콩·2023년 5월 9일

yologa

목록 보기
2/2

프로젝트를 진행하다보면 실행하는 환경이 다양해진다. 본인의 PC에 Application 을 실행하던가, 테스트를 실행하던가, 혹은 개발 서버와 운영 서버를 분리하여 배포할 수도 있다. 다양하게 나누어지는 환경에서 각 환경마다 사용하는 설정이 다른 경우가 발생한다. 동일한 프로젝트에서 다른 설정을 이용하여 실행하도록 각 환경을 정의하는 것을 profile 이라고 부르며, Spring Boot 를 사용하면 profile 을 매우 간단하게 설정할 수 있다.

서비스에 필요한 환경 정의

profile 을 분리하기 위해서는 서비스에서 어떤 환경이 필요한지 정리가 필요하다. 욜로가 서비스에서는 DB 설정에 따른 환경 분리가 필요했으므로, DB 별로 어느 환경에서 어느 설정을 셋팅해두어야 하는지 정리해보았다.

MySQL 환경

MySQL 은 보통 MySQL 그대로 사용하거나 테스트 시 H2 를 사용하기도 한다. H2 는 관계형 데이터베이스를 빠르게 사용하기 위한 임베디드 데이터베이스이다. 속도의 이점 때문에 보통 테스트 시에 사용하며 메모리에 저장되기 때문에 운영 환경에는 적절하지 않다.

  • 로컬에서 테스트 실행 시 어느 것을 사용해도 무방하다.
  • 로컬에서 빌드 시 어느 것을 사용해도 무방하다.
  • 로컬에서 어플리케이션 실행 시 로컬 MySQL 서버에 접근해야 한다.
  • 깃허브에서 빌드 시 어느 것을 사용해도 무방하다. → H2
  • 개발 서버에서 빌드 시 어느 것을 사용해도 무방하다.
  • 개발 서버에서 어플리케이션 실행 시 개발 MySQL 서버에 접근해야 한다.

서비스 운영 중 발생할 수 있는 모든 환경에서 접근해야 하는 MySQL 설정을 정리했다. 개발 서버에서 운영되는 데이터는 개발 MySQL 서버에 저장되도록 하고, 로컬 서버에서는 개발 서버로 배포하기 전에 개발의 편의성을 위해 로컬 MySQL 서버에 접근해야 한다.

그 외의 환경에서는 구현한 기능이 올바르게 동작하는 것을 확인하면 될 뿐, 데이터가 저장되는 위치가 MySQL 인지 H2 인지는 중요하지 않다. 단, 깃허브 서버에서 동작하는 빌드는 개발자가 제어할 수 없는 영역이다. MySQL 은 데이터베이스 특성 상 미리 적절한 데이터베이스와 테이블을 생성해두어야 하는데 깃허브 서버에서는 불가능하다. 따라서 H2 데이터베이스를 선택하였다.

Redis 환경

Redis 는 MySQL 과는 달리 미리 데이터베이스 및 테이블을 정의하지 않아도 되어 데이터 저장이 유연하다. 그래서 깃허브 액션 모듈에서는 Redis 환경을 제공하는 곳도 있다. MySQL 과 마찬가지로 Redis 가 사용되는 환경을 정리해보았다.

  • 로컬에서 테스트 실행 시 어느 것을 사용해도 무방하다. (로컬 Redis 만 가능)
  • 로컬에서 빌드 시 어느 것을 사용해도 무방하다. (로컬 Redis 만 가능)
  • 로컬에서 어플리케이션 실행 시 어느 것을 사용해도 무방하다. (로컬 Redis 만 가능)
  • 깃허브에서 빌드 시 어느 것을 사용해도 무방하다. (자체 Redis 만 가능)
  • 개발 서버에서 빌드 시 어느 것을 사용해도 무방하다. (개발 Redis 만 가능)
  • 개발 서버에서 어플리케이션 실행 시 개발 Redis 서버에 접근해야 한다. (개발 Redis 만 가능)

서비스 운영이 정상적으로 동작해야 하기 때문에 필수적인 환경은 ‘개발 서버에서 어플리케이션 실행 시 개발 Redis 에 접근해야 하는 것’ 뿐이다. 그 외의 모든 환경은 MySQL 과 마찬가지로 구현된 기능이 동작하는 것을 확인만 하면 되므로 어느 Redis 에 저장되어야 하는지는 강제적이지 않다.

하지만 AWS 에서 구축한 Redis 는 동일한 VPC 내의 인스턴스에서만 접근 가능하게만 구축할 수 있다. MySQL 서버인 RDS 도 선택적으로 private 설정을 할 수 있으나, Redis 서버인 ElastiCache 는 반드시 외부에서는 접근할 수 없게 설정되어 있다.

따라서 기능적으로는 어느 Redis 를 선택하든 문제가 없지만, 접근 가능한 Redis 가 한정되어 있기 때문에 접근할 수 있는 Redis 를 설정해준다.

profile 정의

현재까지 결정된, 반드시 설정해야 하는 환경들이다.

서버 환경실행 동작MySQLRedis
로컬테스트로컬 Redis
빌드로컬 Redis
어플리케이션 실행로컬 MySQL로컬 Redis
깃허브빌드H2자체 Redis(= 깃허브 서버 로컬 Redis)
개발 서버빌드개발 Redis
어플리케이션 실행개발 MySQL개발 Redis

분리될 수 있는 최대 경우의 수인 6개로 구분하거나, 공통적으로 묶일 수 있는 ‘로컬/깃허브/개발 서버’ 총 3개로 구분하면 매우 간편하겠지만 테스트 환경과 빌드 환경을 커스텀하기는 어렵다. 다른 개발 블로그에서 gradle 을 이용한 빌드 profile 설정을 본 적이 있으나 매번 실패하였다(…) 빌드 시의 profile 은 상황마다 커스텀하기 어렵기 때문에 기본 profile 을 사용한다.

여기서 문제는 빌드 시의 사용해야 하는 설정들이 다르다는 것이다. MySQL 의 경우 깃허브에서는 반드시 H2 를 사용해야 하며, Redis 의 경우 로컬/깃허브/개발 서버마다 각각의 Redis 를 사용해야 한다. 즉, 모든 환경에서 설정해야 하는 값이 다르다.

이러한 점을 보완하기 위해 테스트 환경에서는 주로 임베디드 데이터베이스를 사용한다. 임베디드 데이터베이스는 속도가 매우 빠르며, 테스트마다 환경이 독립적이기 때문에 테스트를 원활하게 진행할 수 있다는 장점도 있지만, 가장 큰 장점은 각각의 환경에서 별도의 설정 없이 테스트 할 수 있다는 점이다.

MySQL 은 임베디드 디비로 H2 를 사용하고, Redis 는 별도의 의존성을 추가하면 내장 Redis 서버를 구축할 수 있다. 따라서 빌드 환경을 수정한 환경들은 다음과 같다.

서버 환경실행 동작MySQLRedis
로컬테스트H2내장 Redis
빌드H2내장 Redis
어플리케이션 실행로컬 MySQL로컬 Redis
깃허브빌드H2내장 Redis
개발 서버빌드H2내장 Redis
어플리케이션 실행개발 MySQL개발 Redis

빌드 시에는 사실 테스트 코드가 동작한다. 따라서 개발자가 직접 실행하는 ‘테스트’ 환경도 빌드 환경과 통일해주었다. 최종적으로 확정된 profile 은 총 3개이다.

  • test : 테스트 시(+ 빌드) 사용하는 profile
  • local : 로컬에서 Application 을 실행할 때 사용하는 profile
  • dev : 개발 서버에서 Application 을 실행할 때 사용하는 profile

yml 파일을 profile 마다, 설정하는 값마다 분리하였더니 파일의 수가 많아져 폴더로 구분하였다. 개발 서버 환경의 설정값들은 외부에 노출되면 안되므로 서브모듈로 관리한다.

application.yml

spring:
  profiles:
    active: test # 기본 profile
  config:
    import:
      - common/application-logging.yml
      - common/application-service-server.yml
      - yologa-security/application-aws.yml
      - yologa-security/application-jwt.yml
      - yologa-security/application-oauth2.yml
      - yologa-security/application-slack.yml
server:
  port: 8081

기본 profile 을 test 로 설정하여 build 시 별도로 profile 을 설정하지 않아도 되도록 하였다.

0개의 댓글