MSA/MSA 강좌 - 이도원 강사님

👨‍👧‍👦6. Spring Cloud Config

늦은산책 2024. 4. 1. 21:07

💦 Config server 의 중요성

우리는 처음부터 각각의 서비스 설정 정보를 yml 파일을 통해 저장해두었다. 하지만 만약 설정 파일이 변경된다면 서비스 를 다시 빌드하고 배포해야 한다는 단점이 존재했다. 또한 그 설정파일이 모든 서비스에 동일하게 적용되야 하는 값이라면 더욱 불편해진다. 그래서 설정파일 정보를 외부에 설정을 하게 됨으로써 서비스를 더욱 유연하게 운영할 수 있게 된것이다.

 

Spring Cloud Config

  • 분산 시스템에서 서버 클라이언트 구성에 필요한 설정 정보를 외부 시스템에서 관리한다.
  • 하나의 중앙화된 저장소에서 구성요소 관리가 가능하다
  • 각 서비스를 다시 빌드하지 않고, 바로 적용이 가능하다
  • 어플리케이션 배포 파이프라인을 통해 DEV(개발) - UAT(테스트) - PROD(운영) 환경에 맞는 구성 정보를 따로 사용 할 수 있다

  • 왼쪽에 보이는 Git, Secure, File 등으로 설정 파일을 외부에서 관리 할 수가 있다. 이 내용을 Config가 가져와서 서비스에 전달하여 서비스는 해당 설정 정보를 사용한다는 것을 보여준다

💦 설정 정보 파일의 우선순위

우리가 설정하는 설정 정보파일은 application.yml → application-name.yml → application-name-<profile>.yml 순으로 읽을 수 있다

 

💦 Local Git Repository

  • 설정 정보를 관리하기 위해 ecommerce.yml 파일을 원하는 디렉토리에 생성한다

  • 그리고 yml 파일에 간단하게 설정정보 중 토큰의 정보를 담아본다. 그리고 서비스에 토큰 설정 정보는 모두 삭제한다.
Git 의 저장 장소는 local 환경과 remote 환경이 존재한다.
우리가 흔히 아는 add 와 commit 은 local 환경에 등록이 되고 remote로써 등록된 repository에 push를 해준다면 해당 repository와 동기화를 한다.

💦 Spring Cloud Config Server 등록

  • 라이브러리 추가
    • Config Server 단 한개 만 추가
  • Application 클래스에 @EnableConfigServer 를 추가
  • application.yml
server:
  port: 8888

spring:
  application:
    name: config-service
  cloud:
    config:
      server:
        git:
          uri: file://C:\springcloudconfig\git-local-repo
  • 우선 GitHub 가 아닌 로컬의 환경에 저장을 했기에 이런 방식으로 저장 해 줄 수 있다.

UserService에 config 서버 등록

  • 라이브러리 등록
    • config 와 bootstrap
    • bootstrap은 서비스에 내장되어 있는 application.yml 보다 먼저 읽어온다. 또한 가장 먼저 등록되어야 하는 설정 정보를 찾는다.
spring:
  cloud:
    config:
      uri: http://127.0.0.1:8888
      name: ecommerce
  • 우리는 초창기에 ecommerce 라는 yml 파일을 등록해두었고 name을 통해 해당 파일을 불러오는 것을 알 수 있다.
  • 코드 작성 : userservice가 토큰을 잘 가져오는지 확인하기 위해 확인 로직을 health_check에 구성한다
    @GetMapping("/health_check")
    public String status() {
        return String.valueOf("It's Working in User Service"
                + ", port(local.server.port) = " + env.getProperty("local.server.port")
                + ", port(server.port) = " + env.getProperty("server.port")
                + ", token secret = " + env.getProperty("token.secret")
                + ", token expiration time = " + env.getProperty("token.expiration_time"));
    }
  • health-check를 하면 이런 결과를 받아올수 있다.

 

설정 정보 변경하는 3가지 방법

1. 서버 재기동

  • 지금까지 사용했던 방법이고 굉장히 좋지 않은 방법이라는 것을 한눈에 알아볼 수 있다. 혹여 공통적인 설정이 변경되었을때 모두 고쳐줘야 하기 때문이다.

2. Actuator refresh

  • application의 상태를 모니터링 할 수 있다.
  • Metric 수집을 위한 Http End Point를 제공한다.
  • actuator를 사용하면 더이상 서비스를 재부팅하지 않아도 refresh로 서버를 재정비 할 수 있다.

3. Spring Cloud Bus 사용 

  • 다음 과정에서 더욱 자세히 설명

 

Actuator를 사용하기위한 userserviece 재조정

● Websecurity

  • actuator를 uri 에 붙여넣을 것이기 때문에 해당 값을 모두 통과 할 수 있도록 해주어야 한다.

● application.yml

...
management:
  endpoint:
    web:
      exposure:
        include: refresh,health,beans

 

  • actuator가 지원하는 include 방식은 여러개가 있다. 그중 설정 정보를 모두 새롭게 해주는 refresh, health 체크, beans 를 통해 현재 상태를 나타내준다

refresh 를 이용한 설정 정보 입력과 확인

1. 현재 상황 확인

  • 현재 등록되어 있는 토큰값을 확인하기 위해 health_check를 하여 값을 가져왔다.

2. 토큰 값 변경 후 refresh

  • yml 파일에 있는 토큰 값을 수정하고 git 을 통해 local repository에 commit 을 진행
  • 그후 actuator/refresh를 적용하면 commit 된 설정 내용이 서비스의 환경에도 적용된것을 확인 할 수 있다.

API Gateway 에 config 설정 정보 등록

  • 라이브러리
    • config
    • bootstrap
    • actuator
  • bootstrap.yml
spring:
  cloud:
    config:
      uri: http://127.0.0.1:8888
      name: ecommerce
  • application.yml
- id: user-service
  uri: lb://USER-SERVICE
  predicates:
    - Path=/user-service/actuator/**
    - Method=GET, POST
  filters:
    - RemoveRequestHeader=Cookie
    - RewritePath=/user-service/(?<segment>.*), /$\{segment}

...
management:
  endpoints:
    web:
      exposure:
        include: refresh, health, beans, httptrace
  • 요청에 actuator를 넣게 되면서 해당 요청도 그저 지나갈 수 있도록 uri를 등록해 주어야 한다.
  • httptrace : 어플리케이션의 건강 상태를 모니터링하고 문제 해결을 지원한다. 
    • 또한 trace 정보를 가져오려면 Bean 을 등록해 주어야한다. 이러한 설정으로 인해 사용자의 요청과 관련된 정보가 메모리에 저장되고 우리는 actuator/httptrace 엔드포인트로 해당 메모리로 접근하여 정보를 확인 할 수 있다.
@Bean
    public HttpTraceRepository httpTraceRepository() {
        return new InMemoryHttpTraceRepository();
    }

💦 Profiles 를 사용한 config 등록

  • 앞서 application.yml에 대해 이야기 할 떄 가장 마지막에 있던 application-name-<profile>.yml 이 있었다. 그것은 추후에 각 환경에 맞는 설정 파일을 구성할때 사용하게 된다. 
    • ecommerce-dev.yml - 개발 환경
    • ecommerce-uat.yml - 테스트 환경
    • ecommerce-prod.yml - 운영 환경

설정 파일 추가

  • ecommerce-dev.yml
token:
  expiration_time: 86400000 # 만료 기간 -> 하루
  secret: secret-key-dev # 토큰 키
gateway:
  ip: 127.0.0.1
  • ecommerce-prod.yml
token:
  expiration_time: 86400000 # 만료 기간 -> 하루
  secret: secret-key-prod # 토큰 키
gateway:
  ip: 127.0.0.1

 

 

 

 

  • bootstrap in userService
spring:
  cloud:
    config:
      uri: http://127.0.0.1:8888
      name: ecommerce

  profiles:
    active: dev
  • bootstrap in apigateway
spring:
  cloud:
    config:
      uri: http://127.0.0.1:8888
      name: ecommerce

  profiles:
    active: prod
  • dev와 prod 파일을 따로 설정해주고 user에서는 dev, api에서는 prod 파일로 따로 설정해주는 것을 확인 할 수 있다.
    • 이름이 다른 것을 설정할 때는 profiles.active를 사용해서 뒤에 있는 이름을 정확히 한다.

서로의 설정 값을 다르게 한 결과

  1. 회원 가입을 하고 로그인을 진행한다. → 토큰이 dev라는 이름을 달고 나가게 된다
  2. 해당 토큰 값으로 회원가입과 로그인이 아닌 다른 요청을 진행
  3. 그때 apigateway 에서 authorizationFilter가 본인이 가지고 있는 토큰으로 검사하는데 이때 prod 로 토큰값이 잡히면서 401 Unauthorized 에러를 발생하는 것을 알 수 있다.
  4. apigateway에서 active 환경을 dev로 하면 정상 작동 하는 것을 볼 수 있다.

💦 Remote Git Repository

  • 지금까지 Local 의 환경에서 설정 정보를 다룰 수 있다는 것을 확인 할 수 있다. 이제 github의 repository를 등록하여 그곳에 설정 정보를 입력하여 그것으로 설정 환경을 변동시키는 것을 확인해보자
git remote add origin add "깃에서 복사해온 나의 repository"
  • 이렇게 설정을 해서 우리가 입력했던 내용을 모두 push 를 통해 repository에 저장한다.
  • 그후 Config 서버에 목적지를 변경 시켜주어야 한다.
spring:
  application:
    name: config-service
  cloud:
    config:
      server:
        git:
           uri: https://github.com/Tedeeeee/spring-cloud-config.git
  • 이렇게 변경을 해주면 이제 github의 repository에 저장된 데이터를 사용할 수 있다.
    • 만약 private 로 만들었다면 uri 밑에 username(아이디)와 password를 명시해주어야 한다.
  • 서비스에 등록되어 있는 이름은 기존에 사용하던 그대로 사용해도 정상 작동 하는 것을 확인 할 수 있다.

💦 Native Git Repository

  • 깃을 사용하지 않고 그냥 현재 컴퓨터에 존재하는 local file을 이용해서 환경 설정을 변경할 수 있다.
  • bootstrap.yml in config - 설정 파일이 존재하는 곳 config 에 등록을 해주어야 한다.
server:
  port: 8888

spring:
  application:
    name: config-service
  profiles:
    active: native
  cloud:
    config:
      server:
        native:
          search-locations: file:///C:\springcloudconfig\native-file-repo
  • profiles.active를 native로 변경 시키고 native 설정을 켜준다
  • git이 아닌 native.search-locations를 하여 파일의 경로를 지정해준다.