태그: , , , ,

카테고리:

업데이트:


Spring Cloud Config란?

Spring Cloud Config는 분산 시스템에서 외부화된 설정 정보를 서버와 클라이언트에 제공하는 시스템입니다.

기본적으로 Git에 설정 정보를 저장하도록 되어있어 레이블이 지정된 버전의 구성 환경을 쉽게 지원할 뿐만 아니라 콘텐츠 관리를 위한 다양한 도구에 액세스할 수 있습니다.

Spring Cloud Config의 장단점

장점

  • 여러 서버의 성정 파일을 중앙 서버에서 관리할 수 있습니다.
  • 서버를 재배포 하지 않고 설정 파일의 변경사항을 반영할 수 있습니다.

단점

  • Git 서버 또는 설정 서버에 의해 장애가 전파될 수 있습니다.
  • 우선 순위에 의해 설정 정보가 덮어쒸어질 수 있다.

Config의 읽는 순서

Config의 경우 아래 순서대로 정보를 읽어오기 때문에 읽는 순서가 빠른 정보의 경우 덮어씌어질 수 있습니다.

  1. 프로젝트의 applicaiton.yml

  2. 설정 저장소의 application.yml

  3. 프로젝트의 application-{profile}.yml

  4. 설정 저장소의 application-{profile}.yml


Config Server 구현하기

프로젝트 생성하기


프로젝트를 추가로 생성했을 때 프로젝트 구조는 다음과 같아집니다.

[Project Root]
 |-- gradle
 |
 |-- api
 |-- microservices
 |   |-- config-service
 |   |-- gateway-service
 |   |-- composite
 |   |-- post-service
 |   |-- comment-service
 |   '-- user-serivce
 |-- util
 |
 |-- .gitignore
 |-- gradlew
 |-- gradlew.bat
 '-- settings.gradle   

부필요한 Gradle 제거

프로젝트를 추가적으로 생성했으니 지난번과 동일하게 불필요한 gradle 파일을 제거해줍니다.

find microservices -depth -name "gradle" -exec rm -rfv "{}" \;
find microservices -depth -name "gradlew*" -exec rm -rf "{}" \;

settings.gradle 설정하기

config-service또한 일괄적으로 빌드하기 위해 settings.gradle에 추가해줍니다.

include ':api'
include ':util'

include ':microservices:config-service'
include ':microservices:gateway-service'
include ':microservices:composite'
include ':microservices:comment-service'
include ':microservices:post-service'
include ':microservices:user-service'

EnableConfigServer Annotation 설정하기

spring cloud config 서버를 활성화하기 위해서는 다음과 같이 @EnableConfigServer Annotation을 통해 활성화해줘야 합니다.

@EnableConfigServer
@SpringBootApplication
public class ConfigServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServiceApplication.class, args);
    }

}

application.yml 설정하기

Cofig 파일을 Git Repository에서 관리하기 위해서는 다음과 같이 spring.cloud.config.server.git.uri속성으로 git repository를 설정해줍니다.

server:
  port: 8888

spring:
  application:
    name: config-service
  cloud:
    config:
      server:
        git:
          uri: https://github.com/KangHyeon3315/MicroBlogConfig.git # Git Repository URI

Config 정보 저장하기

이제 github에 config 파일을 저장하기 위해 Repository를 생성하고 다음과 같이 config 파일을 작성해 줍니다.

<application-name>-<profile>.yml형식으로 저장해줍니다.

우선 테스트를 위해 다음과 같이 composite-service-dev.yml를 작성해줍니다.

my:
    property: TestValue

Private Repository인 경우

이떄 Git Repository가 Private Repository인 경우 다음과 같이 SSH 키를 등록하고 application.yml에 공개키를 작성해줘야 합니다.

  1. 키 생성하기
    우선 첫번째로, ssh-keygen 명령어를 통해 ssh 공개키와 개인키를 생성해줍니다.

     $ sudo ssh-keygen -f myKey # 공개키 / 개인키 생성
     $ cat myKey.pub # 공개키 확인
     $ cat myKey # 개인키 확인
    
  2. 키 등록하기
    Github에서 Setting > SSH and GPG Keys > New SSH Key를 눌러 공개키를 등록해줍니다.

  3. application.yml 설정
    이제 application.yml에 개인키를 추가해주고 uri를 HTTP 주소에서 SSH 주소로 수정해줍니다.

     spring:
       cloud:
         config:
           server:
             git:
               uri: git@github.com:KangHyeon3315/MicroBlogConfig.git # SSH 주소
               ignore-local-ssh-settings: true
               private-key: |
                   -----BEGIN OPENSSH PRIVATE KEY-----
                   ...
                   -----END OPENSSH PRIVATE KEY-----
    


Config Server의 Docker화

이제 Config Server를 Docker로 구동하도록 설정해보겠습니다.

Dockerfile 작성

우선 Config 서버의 Dockerfile을 다음과 같이 작성해줍니다.

FROM openjdk:17-jdk

EXPOSE 8888

ADD ./build/libs/config-service-0.0.1-SNAPSHOT.jar app.jar

ENTRYPOINT ["java", "-jar", "/app.jar"]

Docker-Compose 작성

그리고 docker-compose에 config 서버를 추가해줍니다.

이때, config client는 config server가 구동된 이후에 구동되도록 설정해야합니다.

따라서, config 서버가 정상적으로 구동됐는지 검사하기위해 healthcheck 속성을 다음과 같이 작성해줍니다.

  config:
    build: microservices/config-service
    mem_limit: 350m

    environment:
        - SPRING_PROFILES_ACTIVE=docker
    
    healthcheck:
      test: [ "CMD-SHELL", "curl --fail http://config:8888/actuator || exit 1" ]
      interval: 1s
      timeout: 1s
      retries: 10


Config Client 설정하기

우선 Config Client에서 Config 정보를 요청하기 위해서는 다음 의존성을 추가해줍니다.

implementation 'org.springframework.cloud:spring-cloud-starter-config'

그리고 다음과 같이 개발 환경 및 docker 환경에서만 config 정보를 가져오도록 profile을 이용해 다음과 같이 설정합니다.

# application.yml

server:
  port: 8000
  error:
    include-message: always

logging:
  level:
    root: info
    com:
      microblog: debug

spring:
  application:
    name: composite-service

  config:
    import: "optional:configserver:"


  cloud:
    consul:
      host: localhost
      port: 8500


# application-dev.yml

spring:
  cloud:
    config:
      uri: http://localhost:8888
      fail-fast: true
      retry:
        initial-interval: 3000
        multiplier: 1.3
        max-interval: 10000
        max-attempts: 20
      profile: dev

# application-docker.yml

spring:
  cloud:
    consul:
      host: consul

    config:
      uri: http://config:8888

server:
  port: 8080

Config 정보 가져오기

이제 config 정보를 가져오도록 다음과 같이 @Value Annotation을 이용해 작성하고 실행하면 정상적으로 프로퍼티를 가져오는 것을 확인 할 수 있습니다.

@RestController
public class CompositeControllerImpl {
    // 생략

    @Value("${my.property}")
    private String myProperty;

    // 생략

    @Override
    public PostComposite getPost(int postId) throws Exception {
        try {
            Post post = getPostFromPostService(postId);
            List<Comment> comments = getCommentFromCommentService(postId);

            return new PostComposite(postId, post.getTitle(), post.getAuthor(), post.getContents() + " " + myProperty, comments);
        } catch (HttpClientErrorException ex) {
            // 생략
        }

    }
}

Test 설정하기

Test 상황에서는 Config 서버에 의존적이지 않아야합니다. Test 환경에서 Config 서버가 실행하고 있지 않을 수 있기 때문입니다.

따라서 다음과 같이 test profile을 작성하고 불러오도록 구현하겠습니다.

# /src/test/resources/application-test.yml

spring:
  config:
    import: ""

  cloud:
    config:
      uri: ""
      fail-fast: true
      retry:
        initial-interval: 3000
        multiplier: 1.3
        max-interval: 10000
        max-attempts: 20
      profile: ""

이제 테스트를 수행할 때 다음과 같이 @ActiveProfiles Annotation을 통해 test profile을 활성화하면 됩니다.

@WebMvcTest
@ActiveProfiles("test")
@ExtendWith(RestDocumentationExtension.class)
public class CompositeControllerImplTest {
  // 생략
}

Docker-Compose 수정하기

마지막으로 Docker Compose에서 일괄적으로 Docker를 실행할 때 Config 서버가 실행 완료된 상태에서 Client들이 실행되어야 합니다.

따라서 Compose 파일을 다음과 같이 작성해 실행 순서를 지정합니다.

composite:
  build: microservices/composite
  mem_limit: 350m
  environment:
    - SPRING_PROFILES_ACTIVE=docker

  # 추가
  restart: on-failure
  depends_on:
    config:
      condition: service_healthy

참고 및 출처

댓글남기기