카테고리 없음

[Spring Cloud Config] 1-2. Spring Cloud Config Server: Composite Environment Repositories

noahkim_ 2025. 9. 2. 22:21

1. Composite Environment Repositories

여러 소스에서 설정을 동시에 가져오기

  • composite 프로필을 사용하여 여러 환경 레포지토리를 한 번에 묶어 쓸 수 있음
  • vault가 포함될 경우, config server에 대한 모든 요청에 vault 토큰을 보내야 함 (X-Config-Token 헤더)
  • 기본적으로 일부 레포지토리 실패 시 전체 composite 요청이 실패함 (failOnCompositeError 옵션으로 무시 가능)

 

예시

더보기
spring:
  profiles:
    active: composite
  cloud:
    config:
      server:
        composite:
          - type: svn
            uri: file:///path/to/svn/repo
          - type: git
            uri: file:///path/to/rex/git/repo
          - type: git
            uri: file:///path/to/walter/git/repo
spring:
  profiles:
    active: git, vault
  cloud:
    config:
      server:
        git:
          uri: file:///path/to/git/repo
          order: 2
        vault:
          host: 127.0.0.1
          port: 8200
          order: 1
  • order로 충돌 시, 우선순위 부여 가능

 

설정) 실패 무시하기

더보기
spring.cloud.config.server.failOnCompositeError: false

 

2. Custom Composite Environment Repositories

  • 직접 EnvironmentRepository 빈을 구현해 composite에 포함시킬 수 있음
  • 우선순위를 제어하려면 Ordered 인터페이스를 함께 구현하기

 

예시

더보기
@Component  // ★ 빈으로 등록
public class FeatureFlagEnvironmentRepository implements EnvironmentRepository, Ordered {

    /**
     * Composite 질의 시 호출됨.
     * @param application 요청한 앱명 (예: "user-service")
     * @param profile     요청 프로필 (예: "default" 또는 "prod")
     * @param label       라벨/브랜치 (예: "main")
     */
    @Override
    public Environment findOne(String application, String profile, String label) {
        // 1) 응답 컨테이너 생성
        Environment env = new Environment(application, profile == null ? null : profile.split(","), label);

        // 2) 외부 API/메모리/파일 등에서 값 수집 (여긴 데모로 하드코딩)
        Map<String, Object> props = new HashMap<>();

        // 예: 서비스/프로필에 따라 플래그 분기
        if ("user-service".equals(application)) {
            boolean isProd = profile != null && profile.contains("prod");
            props.put("feature.signup.v2.enabled", !isProd); // prod에선 끄고 그 외엔 켜기
            props.put("banner.message", isProd ? "Welcome PROD" : "Welcome DEV");
        }

        // 3) 수집한 맵을 PropertySource로 추가
        //    이름은 구분 가능한 식별자면 아무거나 가능
        env.add(new PropertySource("custom:feature-flags:" + application + ":" + profile, props));
        return env;
    }

    /** 숫자 작을수록 우선순위 ↑ (Vault/Git보다 먼저 적용하려면 더 작은 값) */
    @Override
    public int getOrder() {
        return 1; // 예: 1이면 Vault(order=3), Git(order=5)보다 우선
    }
}

 

출처