Spring Cloud Config Server/Client (RabbitMQ & Cloud Bus)

2023. 7. 22. 16:05·📘 Backend/Spring Cloud

📘 Spring Cloud Config Server

Spring Cloud Config 는 여러 서비스 들의 설정 파일을 외부로 분리해 하나의 중앙 설정 저장소 처럼 관리 할 수 있도록 해주며 특정 설정 값이 변경시 각각의 서비스를 재기동 할 필요없이 적용이 가능하도록 도와준다.

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

하지만 이것이 모든 문제를 해결해주지는 않는다. Spring Cloud Config를 이용하면 다음의 문제들을 겪을 수 있으므로 주의해야 한다.

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


Spring Cloud Config 설정 파일 우선 순위

설정 파일은 크게 다음의 위치에 존재할 수 있으며 다음의 순서대로 읽어진다. 나중에 읽어지는 것이 우선순위가 높다.

  • 프로젝트의 application.yaml
  • 설정 저장소의 application.yaml
  • 프로젝트의 application-{profile}.yaml
  • 설정 저장소의 {application name}/{application name}-{profile}

만약 읽어지는 순서대로 읽다가 동일한 값을 지니는 설정 정보가 있다면 덮어 씌워지므로 주의해야 한다. 예를 들어 'hello'이라는 이름의 애플리케이션에 local 프로파일인 환경변수가 로컬의 appliation.yaml, application-local.yaml에 있고, 설정 저장소의 application.yaml, hello/hello-local.yaml에도 있다면 다음의 순서대로 읽어진다.

  • 프로젝트의 application.yaml
  • 설정 저장소의 application.yaml
  • 프로젝트 application-local.yaml
  • 설정 저장소의 hello/hello-local.yaml

최종적으로 읽혀 적용되는 환경변수 값은 설정 저장소의 hello/hello-local.yaml 의 값이다. 만약 설정 정보가 산개되어 있다면 오히려 관리가 복잡해질 수 있으며, 동작 과정을 모른다면 장애가 될 수 있으므로 주의하도록 하자.


Cloud Config Repository 생성

  • Github에서 Private으로 Yaml 파일들을 저장할 Repository를 만든다.
  • 이 Repository는 추후 만들 Cloud Config Server와 SSL 통신으로 Yaml파일을 불러오기 위함이다.

SSH Key 미리 생성해두기

  • ssh-keygen -m PEM -t ecdsa -b 256 -C "Github 계정" -f 키파일명
  • 생성된 공개키를 Github 계정에 추가
  • cat key.pub
  • 개인키 복사
  • host-key와 host-key-algorithm 확인 후 Yml파일에 등록 = ssh-keyscan -t ecdsa github.com

📘 Cloud Config Server 설정

application.yml

spring:
  cloud:
    config:
      server:
        git:
          # config server가 참조할 yml 파일들을 모아둔 repository의 주소
          uri: Git SSH 주소로 변경
          # config server가 참조할 repository의 branch 이름은 main이다.
          default-label: main
          ignore-local-ssh-settings: true
          private-key: |
            -----BEGIN EC PRIVATE KEY-----
            비밀키는 소중해요
            비밀키는 소중해요
            비밀키는 소중해요
            -----END EC PRIVATE KEY-----
          host-key: AAAA~~~
          host-key-algorithm: ecdsa~~
          search-paths: src/**
        # 모든 설정 정보를 암호화 시키겠다는 의미
        encrypt:
          enabled: false

# actuator 설정
# management 아래의 설정들 -> actuator의 설정 정보들.
# 설정 파일의 정보가 변경된 경우에 refresh를 통해서 새로운 설정 정보를 가져올 수 있다.
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    shutdown:
      enabled: true

# 암호화를 시키는데 사용되는 Key 값
encrypt:
  key: key-brian

암호화된 값을 yml에 넣을때 꼭 "{cipher}암호화된값" 의 형식으로 넣어야 동작함.

config 서버는 기본적으로 8888번 포트를 사용하므로 맞춰주도록 하자. 그 외에 설정 파일이 있는 위치와 디렉토리 등을 잡아주면 된다.

  • uri: 설정파일이 있는 깃 주소
  • default-label: 깃 주소의 브랜치 이름
  • private-key : Config-Repository를 Private 레포로 만들었기 때문에 SSL 통신으로 해야하기 떄문에 개인키를 등록한다.

ssh-keygen -m PEM -t ecdsa -f 파일명


마지막으로 메인 클래스에 @EnableConfigServer를 붙여주면 서버 구성이 끝난다.

Config Server를 실행시켜서 Config Repository의 파일명을 '/'를 기준으로 나눠서 호출을 해보면 잘 나오는걸 볼 수 있다.
ex:
Config-Repository의 파일명 : remind-security.yml
API 호출 : http://localhost:8888/remind/security


Spring Cloud Config Server에서 Cloud Repository의 Yml 파일 호출 성공

img


📘 Spring Cloud Config Client 설정

GET /{application}/{profile}[/{label}]
GET /{application}-{profile}.yml
GET /{label}/{application}-{profile}.yml
GET /{application}-{profile}.properties
GET /{label}/{application}-{profile}.properties

application : Spring Cloud Config Client의 application.properties (application.yml)파일에 정의한 spring.application.name 속성 값을 의미한다.
profile : Spring Cloud Config Client의 application.properties (application.yml) 파일에 정의한 spring.profiles.active 속성 값을 의미한다.
label : Optional 값으로, Git branch 정보를 의미한다.


즉, 내 Cloud Config Client 서버로 대입하면 GET /security/local/main


Client 서버 의존성 추가

  • Spring Cloud Config Client
  • Spring Boot Actuator
ext {
    set('springCloudVersion', "2022.0.3")
}

dependencies {
  implementation 'org.springframework.cloud:spring-cloud-config-client'
  implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

Client 서버 application.yml 파일에 Actuator 설정 추가, Config Server 등록

spring:
  config:
  import: "optional:configserver:http://localhost:8888" # Config-Server

# Actuator 설정
management:
  endpoints:
    web:
      exposure:
        include: "*"

이제 Config Server가 Config Repository를 스캔해서 가져온 파일들을,
어플리케이션 환경 엔드포인트에 맞게 잘 가져오는지 테스트를 위한 클래스를 생성한다.

@Getter
@Component
@RefreshScope // Config.yml 파일 변경 시 변경된 내용을 actuator를 통해 변경값을 갱신
public class CloudConfig {

    @Value("${spring.security.oauth2.client.registration.google.client-id}")
    private String oauthClientId;

    @Value("${spring.security.oauth2.client.registration.google.client-secret}")
    private String oauthClientPw;

    @Override
    public String toString() {
        return "CloudConfig{" +
                "oauthClientId='" + oauthClientId + '\'' +
                ", oauthClientPw='" + oauthClientPw + '\'' +
                '}';
    }
}

컨트롤러 생성

@RestController
@RequestMapping("/cloud")
@RequiredArgsConstructor
public class CloudController {
    private final CloudConfig config;

    @GetMapping("/remind-security")
    public String loadSecurityConfig() {
        return config.toString();
    }
}

이 후 Client로 Request를 보내보면 Config-Repoisitory의 Yml 값들이 잘 불러와진걸 볼 수 있다.


📘 @RefreshScope를 이용한 Config 변경 사항 적용

Config Server/Client가 모두 실행중인 상태에서 진행한다.

  • Yml 설정 값 변경
  • http://localhost:8080/actuator/refresh 를 호출하여 변경값 적용

위의 방법으로 하면 변경사항은 적용될 수 있지만 모든 인스턴스에 호출해주어야 하므로 비효율적인 작업이 된다.
이를 해결하기 위한 2가지 방법이 있다.

  • Eureka 엔진으로 모든 서비스를 조회한 후 /actuator/refresh 종단점을 직접 호출하는 스크립트 작성
  • Spring Cloud Bus / RabbitMQ로 변경 내용을 전파 (BroadCasting)

자동화를 위해 RabbitMQ를 활용하여 환경설정 변경 시 전파하는 방법을 알아보자.
Spring Cloud Bus를 이용하면 실행되고 있는 인스턴스의 수나 위치에 관계없이 환경설정 변경을 전파할 수 있다.

  • 실행중인 인스턴스는 하나의 메시지 브로커를 통해 변경 이벤트 구독
  • 변경 이벤트가 발생하면 각 인스턴스는 변경된 설정 정보를 읽어와서 Local에 Casing된 정보 갱신
  • 한 인스턴스의 /actuator/busrefresh 종단점이 호출되면 모든 메시지 브로커를 통해 변경 내용 모두 전파하는 방식이다.

📘 RabbitMQ

RabbitMQ 설치 가이드

docker run -it --rm --name rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.12-management

컨테이너를 실행시키고 http://locahost:15672로 접속하면 로그인 화면이 나온다.

  • username : (Default) guest
  • password : (Default) guest

접속하면 Connections에 접속된 Config Client를 확인할 수 있고 Excjamges에서 Spring Cloud Bus가 연결된 걸 확인할 수 있다.

img


📘 Config Client 의존성 추가, Yml 설정

    implementatin 'org.springframework.cloud:spring-cloud-starter-bus-amqp'
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

Config Client 인스턴스 1개 추가

IntelliJ에서 Edit Configuration - 실행지점을 1개 더 늘려준다.

실행 포트가 다른 인스턴스를 2개 실행시켜준다.

  • 이후 Yml의 설정을 임의로 변경
  • POST /actuator/busrefresh
  • Config Client 8080. 8081에서 변경된 내용 확인
저작자표시 (새창열림)

'📘 Backend > Spring Cloud' 카테고리의 다른 글

Spring Cloud Stream + RabbitMQ Binder  (2) 2025.02.03
Distributed Log Tracing (Zipkin + Spring Cloud Sleuth)  (4) 2024.12.27
Spring Cloud Config  (0) 2023.04.04
Spring Cloud Gateway (Eureka)  (0) 2023.04.04
'📘 Backend/Spring Cloud' 카테고리의 다른 글
  • Spring Cloud Stream + RabbitMQ Binder
  • Distributed Log Tracing (Zipkin + Spring Cloud Sleuth)
  • Spring Cloud Config
  • Spring Cloud Gateway (Eureka)
신건우
신건우
조용한 개발자
  • 신건우
    우주먼지
    신건우
  • 전체
    오늘
    어제
    • 분류 전체보기 (422)
      • 📘 Frontend (71)
        • Markup (1)
        • Style Sheet (2)
        • Dart (8)
        • Javascript (12)
        • TypeScript (1)
        • Vue (36)
        • React (2)
        • Flutter (9)
      • 📘 Backend (143)
        • Java (34)
        • Concurrency (19)
        • Reflection (1)
        • Kotlin (29)
        • Python (1)
        • Spring (42)
        • Spring Cloud (5)
        • Message Broker (5)
        • Streaming (2)
        • 기능 개발 (5)
      • 💻 Server (6)
        • Linux (6)
      • ❌ Error Handling (11)
      • 📦 Database (62)
        • SQL (31)
        • NoSQL (2)
        • JPQL (9)
        • QueryDSL (12)
        • Basic (4)
        • Firebase (4)
      • ⚙️ Ops (57)
        • CS (6)
        • AWS (9)
        • Docker (8)
        • Kubernetes (13)
        • MSA (1)
        • CI & CD (20)
      • 📚 Data Architect (48)
        • Data Structure (10)
        • Algorithm (8)
        • Programmers (17)
        • BaekJoon (5)
        • CodeUp (4)
        • Design Pattern (4)
        • AI (0)
      • ⚒️ Management & Tool (8)
        • Git (7)
        • IntelliJ (1)
      • 📄 Document (10)
        • Project 설계 (6)
        • Server Migration (3)
      • 📄 책읽기 (2)
        • 시작하세요! 도커 & 쿠버네티스 (2)
      • 🎮 Game (4)
        • Stardew Vally (1)
        • Path of Exile (3)
  • 블로그 메뉴

    • 링크

      • Github
    • 공지사항

    • 인기 글

    • 태그

      Lock #Thread #Concurrency
      React #Markdown
      GStreamer #Pipeline
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.0
    신건우
    Spring Cloud Config Server/Client (RabbitMQ & Cloud Bus)
    상단으로

    티스토리툴바