Spring Cloud Config

ayboori·2024년 8월 5일
0

Spring

목록 보기
16/24

Spring Cloud Config란?

추가 자료

  • Spring Cloud Config는 분산 시스템 환경에서 중앙 집중식 구성 관리를 제공하는 프레임워크입니다.
  • 애플리케이션의 설정을 중앙에서 관리하고, 변경 사항을 실시간으로 반영할 수 있습니다.
  • Git, 파일 시스템, JDBC 등 다양한 저장소를 지원합니다.
  • yml 파일에 설정 정보, 설정과 무관한 정보 (@Value로 호출 가능)등의 변동이 발생할 때 재배포 (어플리케이션을 내렸다 올려야 함, 서비스에 문제가 발생할 수 있음)를 방지하기 위해 사용

주요 기능

  • 중앙 집중식 구성 관리: 모든 마이크로서비스의 설정을 중앙에서 관리합니다.
  • 환경별 구성: 개발, 테스트, 운영 등 환경별로 구성을 분리하여 관리할 수 있습니다.
  • 실시간 구성 변경: 설정 변경 시 애플리케이션을 재시작하지 않고도 실시간으로 반영할 수 있습니다.

Spring Cloud Config 서버 설정

Config 서버 구성

  • Config 서버는 설정 파일을 저장하고 제공하는 역할을 합니다.
  • build.gradle 파일에 필요한 의존성을 추가합니다.
    dependencies {
        implementation 'org.springframework.cloud:spring-cloud-config-server'
        implementation 'org.springframework.boot:spring-boot-starter-web'
    }
    

서버 애플리케이션 설정

  • Spring Boot 애플리케이션에서 Config 서버를 설정합니다.
    @SpringBootApplication
    @EnableConfigServer
    public class ConfigServerApplication {
        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApplication.class, args);
        }
    }
    

설정 파일 구성

  • application.yml 파일에서 Config 서버의 설정을 정의합니다.
    
    server:
      port: 8888
    
    spring:
      cloud:
        config:
          server:
            git:
              uri: https://github.com/my-config-repo/config-repo
              clone-on-start: true
    

Spring Cloud Config 클라이언트 설정

클라이언트 구성

  • Config 클라이언트는 Config 서버에서 설정을 받아오는 역할을 합니다.
  • build.gradle 파일에 필요한 의존성을 추가합니다.
    dependencies {
        implementation 'org.springframework.cloud:spring-cloud-starter-config'
        # 맨 뒤에 server x
    }

8.3.2 설정 파일 구성

  • 클라이언트의 application.yml 파일에서 Config 서버의 설정을 정의합니다.
    
    spring:
      application:
        name: my-config-client
      cloud:
        config:
          discovery:
            enabled: true
            service-id: config-server # eureka에 의해 관리됨
         
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:19090/eureka/

환경별 구성 관리

환경별 설정 파일

  • Config 서버는 환경별로 다른 설정 파일을 제공할 수 있습니다.
  • 예를 들어, application-dev.yml, application-prod.yml 파일을 Git 저장소에 저장 (Config Server) 하여 환경별 설정을 관리합니다.

프로필 사용

  • Spring Boot 애플리케이션에서 프로필을 사용하여 환경을 구분할 수 있습니다:
    spring:
      profiles:
        active: dev # 위의 application-dev.yml 설정을 가져와 적용

실시간 구성 변경 방법

❗ 실시간 구성 변경을 반영하는 방법에는 여러 가지가 있습니다.
Spring Cloud Bus를 사용하는 방법, 수동으로 /actuator/refresh 엔드포인트를 호출하는 방법, Spring Boot DevTools를 사용하는 방법, 그리고 Git 저장소를 사용하는 방법, ...

각 방법은 상황에 따라 적절히 선택하여 사용할 수 있습니다. Spring Cloud Bus는 메시징 시스템을 통해 실시간으로 설정 변경 사항을 전파하는 데 매우 유용하며, Git 저장소를 사용하면 설정 파일의 버전 관리를 쉽게 할 수 있습니다. Spring Boot DevTools는 주로 개발 환경에서 유용하게 사용됩니다.

Spring Cloud Bus

Config와의 비교 및 설명

  • MQ(Message Queue) Handler
  • Spring Cloud Bus를 사용하면 설정 변경 사항을 실시간으로 클라이언트 애플리케이션에 반영할 수 있습니다. 이를 위해서는 메시징 시스템(RabbitMQ 또는 Kafka 등)을 사용하여 변경 사항을 전파해야 합니다.

수동 구성 갱신

메시징 시스템을 사용하지 않고 로컬에서 사용하는 방법

  • /actuator/refresh 엔드포인트 사용 Spring Cloud Bus를 사용하지 않는 경우, 클라이언트 애플리케이션에서 수동으로 설정을 갱신할 수 있습니다. 이를 위해 Spring Actuator의 /actuator/refresh 엔드포인트를 사용할 수 있습니다.

설정 갱신 절차
1. Config 서버에서 설정 파일을 변경합니다.
2. 클라이언트 애플리케이션의 /actuator/refresh 엔드포인트를 POST 요청으로 호출하여 변경된 설정을 반영합니다.

이 방법은 간단하지만, 각 클라이언트 애플리케이션에서 수동으로 엔드포인트를 호출해야 합니다.

Spring Boot DevTools 사용

참고
Spring Boot DevTools를 사용하면 개발 환경에서 파일 변경 (브라우저로 전송되는 내용들에 대한 코드 변경) 을 자동으로 감지하고 애플리케이션을 재시작할 수 있습니다. 이는 classpath 내의 파일 변경도 포함됩니다.

설정 파일이 아닌 엔티티 추가, 필드 추가,... h2 데이터베이스 사용 시 h2 콘솔도 활성화 등등 변경 사항 모두 반영

저장소 사용

Spring Cloud Config 서버가 Git 저장소에서 설정 파일을 읽어오도록 설정할 수 있습니다. 이는 설정 파일의 변경 사항을 쉽게 반영하고, 여러 서비스 간에 일관된 구성을 유지하는 데 유용합니다.

Spring Cloud Config 실습

실습 부분 다시 찬찬히 보면서 학습하기...

❗ 컨피그 서버를 생성하고 product 애플리케이션이 local 에서 동작할 때 포트 정보 및 메시지를 컨피그 서버에서 가져옵니다.
컨피그 서버의 메시지를 변경하여 product 애플리케이션의 message가 갱신되는 모습을 확인합니다.

config의 포트와 메시지를 product-local로 가져온다.
사용자는 product를 통해 메시지를 확인하고, acuator/refresh를 통해 갱신

이번 실습에서는 리소스 서버에 있는 설정 파일을 사용해보겠습니다.

Config-server

  • ConfigApplication.java
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.config.server.EnableConfigServer;
    
    @SpringBootApplication
    @EnableConfigServer 
    public class ConfigApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(ConfigApplication.class, args);
    	}
    
    }
    
  • resources/appication.yml
    server:
      port: 18080 
    
    spring:
      profiles:
        active: native
      application:
        name: config-server
      cloud:
        config:
          server:
            native:
              search-locations: classpath:/config-repo  # 리소스 폴더의 디렉토리 경로
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:19090/eureka/
  • resources 안에 config-repo라는 폴더를 생성한 후 아래의 두 파일을 만듭니다.
    • product-service.yml
      server:
        port: 19093
      
      message: "product-service message"
    • product-service-local.yml
      server:
        port: 19083
      
      message: "product-service-local message"

Product-service

  • build-gradle의 디펜던시에 config 를 추가합니다.
    dependencies {
    	implementation 'org.springframework.boot:spring-boot-starter-actuator'
    	implementation 'org.springframework.cloud:spring-cloud-starter-config'
    	implementation 'org.springframework.boot:spring-boot-starter-web'
    	implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    	compileOnly 'org.projectlombok:lombok'
    	annotationProcessor 'org.projectlombok:lombok'
    	testImplementation 'org.springframework.boot:spring-boot-starter-test'
    	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    }
  • application.yml
    server:
      port: 0  # 임시 포트, 이후 Config 서버 설정으로 덮어씌움
    
    spring:
      profiles:
        active: local # config 서버의 local yml 파일을 가져와서 실행, port와 message 변경될 것
      application:
        name: product-service
      config:
        import: "configserver:"
      cloud:
        config:
          discovery:
            enabled: true
            service-id: config-server
    
    # acuator에서 refresh 활성화
    management:
      endpoints:
        web:
          exposure:
            include: refresh
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:19090/eureka/
    
    message: "default message" # 이 앱이 config를 타지 않았다면 0번 포트, default message
  • ProductController.java
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @RefreshScope 애노테이션은 Spring 애플리케이션의 빈이 설정 변경을 반영할 수 있도록 하는 역할을 합니다.
     * 기본적으로 Spring 애플리케이션의 빈은 애플리케이션이 시작될 때 초기화되고, 설정 값이 변경되더라도 해당 빈은 갱신되지 않습니다.
     * 이 애노테이션을 사용하면 /actuator/refresh 엔드포인트를 호출하여 설정 변경 사항을 동적으로 반영할 수 있습니다.
     */
    @RefreshScope
    @RestController
    @RequestMapping("/product")
    public class ProductController {
    
        @Value("${server.port}") // 애플리케이션이 실행 중인 포트를 주입받습니다.
        private String serverPort;
    
        @Value("${message}")
        private String message; // 위에서 선언한 default message
    
        @GetMapping
        public String getProduct() {
            return "Product detail from PORT : " + serverPort + " and message : " + this.message ;
        }
    }
    

RUN

  • 유레카 서버 > 컨피그 서버 > 상품 순으로 실행합니다.
  • 상품이 실행될때 로그의 포트를 확인합니다. 19083 으로 할당됨을 볼 수 있습니다.

    port를 0으로 설정했으나 config 서버를 통해 가져온 yml 파일의 값으로 설정 파일 변경됨

  • http://localhost:19083/product 을 호출하면 포트와 메시지를 확인 할 수 있습니다.
  • config-server 의 product-service-local.yml 파일의 message를 수정하고 config-server 를 재시작 합니다.
    server:
      port: 19083
    
    message: "product-service-local message updated"
  • talend api tester를 실행하고 http://localhost:19083/actuator/refresh 로 post 요청을 합니다. 응답으로 메시지가 업데이트 됨을 확인 할 수 있습니다.
  • 다시 http://localhost:19083/product를 호출 하면 메시지가 변경된 것을 확인 할 수 있습니다.
profile
프로 개발자가 되기 위해 뚜벅뚜벅.. 뚜벅초

0개의 댓글