1. Spring Cloud Config란?
Spring Cloud Config는 분산 시스템에서 외부화된 설정 정보를 중앙 집중화하여 관리하기 위해 사용합니다.
Config 서버는 설정 정보를 중앙 저장소에서 읽어와 클라이언트 애플리케이션에 제공하고, 클라이언트는 Config Server로부터 설정을 가져와 동적으로 업데이트가 가능합니다.
1-1 Spring Cloud Config의 장점과 단점
Spring Cloud Config의 장점과 단점에 대해 알아보도록 하겠습니다.
1. 중앙 집중화된 설정 관리
- 여러 마이크로서비스에서 동일 설정이 필요하거나, 분산되어 있는 경우 Config Server를 통해 한 곳에서 관리가 가능하다.
2. 환경별 설정 관리
- 개발, 테스트, 운영 등 환경에 따라 다른 설정을 효율적으로 관리할 수 있다.
3. 동적 업데이트
- 애플리케이션을 재시작하지 않고 설정 변경 사항을 반영할 수 있다.
ex) DB 변경이 생기거나, 수치가 변경된 경우 이 전에는 서버 내부에 설정파일들이 존재해 변경시마다 애플리케이션을 새로 빌드하고 배포하는 불편함이 발생 -> Spring Cloud Config를 사용하면 동적으로 변경사항을 반영할 수 있다.
(실제로 예전에 프로젝트를 진행했을 때 DB변경이 자주 일어나서..골치 아팠던 경험이 새록새록 떠올랐습니다...)
장점을 요약해보자면 여러 서버의 설정 파일을 중앙 서버에서 관리할 수 있으며 동적으로 변경사항을 반영할 수 있다라는 것입니다. 하지만 장점만 존재하는 것이 아니었으니 단점 또한 존재합니다.
1. 장애 발생
Config Server가 다운되거나 네트워크 문제가 발생할 경우 설정 데이터를 읽지 못해 서비스에 영향을 미칠 수 있습니다.
2. 추가 인프라
Config Server를 위한 추가적인 인프라가 필요할 뿐더러 Config Server의 장애 발생시 대비하기위한 추가적인 인프라가 필요할 수 있다.
지금까지 Spring Cloud Config에 대한 장점과 단점에 대해 알아보았습니다. 그럼 지금부터는 본격적으로 Spring Cloud Config를 프로젝트에 적용해보도록 하겠습니다.
2. Spring Cloud Config 구축하기
2-1 모듈 생성 및 Gradle 의존성 추가
설정 파일들 관리할 중앙 서버를 구성하기 위해 새로운 모듈을 생성하고 spring-cloud-config-server 의존성을 추가해줍니다.
ext {
set('springCloudVersion', "2023.0.5")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-config-server'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
2-2 Spring Cloud Config Server의 application.yml에 설정 파일 추가하기
추가가 완료되었다면 설정 서버의 application.yml 파일에 아래와 같은 내용을 추가합니다.
server:
port: 8888
spring:
application:
name: config
cloud:
config:
server:
git:
uri: //설정 파일 위치한 Github 레파지토리 주소
search-paths: // 설정 파일들의 경로
default-label: //브랜치 이름
- port: config server는 기본적으로 8888번 포트를 사용
- uri: 설정 파일이 위치한 Github 레파지토리 주소
- search-paths: Github 레파지토리 안의 설정 파일들이 위치한 경로
- default-label: 브랜치 이름
2-3 @EnableConfigServer 어노테이션 추가
@EnableConfigServer를 추가해 Spring Cloud Config Server를 활성화해줍니다.
@SpringBootApplication
@EnableConfigServer
public class ConfigServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServiceApplication.class, args);
}
}
지금까지의 설정을 마무리하면 이제 github repository에 접근하기 위한 추가적인 작업이 필요합니다.
현재 github repository는 private로 되어있어 접근이 불가능합니다. github repository에 접근하기 위한 SSL연결 설정을 진행해보도록 하겠습니다.
3. Private Github Repository 접근을 위한 설정
3-1 설정 서버에서 비대칭 키 생성하기
설정 서버가 깃 저장소에 연결할 때 사용할 비대칭 키를 생성해줍니다.
ssh-keygen -m PEM -t ecdsa -b 256
cat명령어를 통해 생성된 공개키를 확인할 수 있습니다.
cat ~/.ssh/id_ecdsa.pub
3-2 생성된 key를 Github Repository에 등록하기
위에 생성된 key를 Settings -> deploy keys에 저장합니다.
3-3 Spring Cloud Config Server의 yml 파일 수정하기
spring:
application:
name: config
cloud:
config:
server:
git:
default-label: main
uri: git@github.com:minjun7984/doridos-msa-config.git //SSH접속 주소
search-paths: config
ignore-local-ssh-settings: true
host-key:
host-key-algorithm: ecdsa-sha2-nistp256 //알고리즘
private-key: |
-----BEGIN EC PRIVATE KEY-----
key~~~~~~넣어주십쇼
-----END EC PRIVATE KEY-----
passphrase: key 생성시 작성한것
- default-label: 깃 주소의 브랜치 이름
- uri: 설정 파일이 있는 깃 주소 (ssh접속을 이용 github repository의 code -> ssh 칸 선택후 복사해 가져오자)
- search-paths: 탐색경로
- ignore-local-ssh-settings: true 설정시 로컬 ssh 설정을 무시하고 자체적으로 구성된 설정 연결을 사용
- host-key: ssh호스트 키를 입력
- host-key-algoritm: 공개키 생성 시 사용한 알고리즘
- private-key: 생성한 공개키를 입력 (-> | 처음에 입력해야함!)
host-key 조회 방법
ssh-keyscan -t ecdsa github.com
빨간 곳으로 가려진 부분을 복사해 yml파일에 붙여넣기 해줍니다.
private-key 조회 방법
cat ~/.ssh/id_ecdsa
키가 저장된 경로로 조회하면 키를 확인할 수 있습니다.(필자는 /.ssh 경로에 존재)
번외) token 방식의 접속을 하려면
username:
password:
username에 계정 이름을, password에 Github 홈페이지 settings -> Developer settings -> token 생성 및 권한 설정을 해준 후 값을 복사해 넣어줍니다.
3-4 동작 테스트
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
(스프링 클라우드 공식문서에서 제공)
Spring cloud config server가 갖는 endpoint는 위와 같습니다.
제 유저 서비스의 설정파일은 user-service-local.yml 형식으로 저장되어 있기 때문에 localhost:8888/user-service/local 의 경로로 요청을 보내면 private repository에 저장되있는 yml파일의 내용이 정상적으로 잘 출력되는 것을 볼 수 있습니다.
3-5 클라이언트 서버 설정
각 서비스에서 설정 서버에서 설정 정보를 받아오기 위해 Spring Cloud Config Client 설정을 추가해줍니다.
implementation 'org.springframework.cloud:spring-cloud-config-client'
server:
port: 8081
spring:
application:
name: user-service
profiles:
active: local
config:
import: optional:configserver:http://localhost:8888
user-service-local.yml를 기준으로 위와 같이 설정해줍니다.
- application : yml 파일의 application 이름을 넣어준다. (user-service)
- profiles : yml 파일 profiles 설정 (local)
- cofig: config 서버 연결을 위한 url 입력
해당 설정을 마치고 서버를 실행한 후 API Gateway에 요청을 보내면 정상적으로 응답이 오는 것을 확인할 수 있습니다.
4. 동적으로 설정파일 변경하기 (Spring Cloud Bus + RabbitMQ)
지금까지 Spring Cloud Config을 구성하는 작업을 진행했습니다.
하지만 아직 동적으로 설정파일을 변경하기 위해서는 추가적인 작업이 필요합니다. Spring Cloud Config는 처음 시작 시 설정정보를 가져와 캐시해 보관해두기 때문에 설정 파일이 변경되었을 경우 이 변경사항을 알려줄 추가적인 작업이 필요합니다.
이를 위해 Spring Cloud Config Client의 actuator를 호출해 refresh하는 방법도 존재하지만 애플리케이션이 갈수록 많아진다고 가정했을 경우 refresh를 수동으로해줘야 하는 단점이 있습니다.
이런 단점을 개선하기 위해서
Spring cloud bus를 사용해 설정파일을 변경하는 작업을 진행해보겠습니다. 흐름은 아래 그림과 같습니다.
1. Spring Config Server와 연결되어 있는 Spring Cloud Bus가 /actuator/busrefresh 요청을 보낼 시 구독하고 있는 마이크로 서비스에게 메시지를 보낸다.
2. 구독하고 있는 마이크로서비스들이 메시지를 받고 설정 정보를 업데이트하는 refresh를 수행한다.
그럼 본격적으로 Spring Cloud Bus를 구성해보도록 하겠습니다.
4-1 RabbitMQ 설치
docker pull rabbitmq
이미지를 다운받은 후 docker run 명령어를 통해 컨테이너를 생성해줍니다.
4-2 RabbitMQ gradle 설정 추가
Gateway Service, Config Server, 각 마이크로 서비스에 의존성을 추가해줍니다.
implementation 'org.springframework.cloud:spring-cloud-starter-bus-amqp'
4-3 yml파일 수정하기
아래와 같은 내용들을 각 서버의 yml 파일에 추가해줍니다.
(name 부분은 각 서비스의 이름에 맞게 변경합니다.)
spring:
application:
name: config
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
include: refresh,health,busrefresh
4-4 동작 확인
Github에 올라간 user-service-local.yml파일에 토큰 만료시간을 변경한 후 busrefresh 요청을 보낸 후 결과를 확인하면
rabbitmq를 구독하고 있는 다른 마이크로서비스에도 메시지가 전달된 것 을 볼 수 있습니다.
값 변경을 확인하기 위해 간단하게 만료시간을 출력하도록 코드를 추가하고, 테스트를 진행하면 정상적으로 값이 변경된 것을 확인할 수 있습니다.
public String createAccessToken(String email, UserType type) {
Date now = new Date();
System.out.println(validityInMilliseconds);
return Jwts.builder()
.setSubject(email)
.claim(AUTHORIZATION_KEY, type)
.setIssuedAt(now)
.setExpiration(new Date(now.getTime() + validityInMilliseconds))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
참고
https://mangkyu.tistory.com/253
[Spring] Spring Cloud Config 도입하기 및 private 레포지토리 SSL로 연결 설정 및 privateKey 암호화
이번에는 Spring Cloud Config에 대해 간단히 알아보고, 설정해보도록 하겠습니다. 1. Spring Cloud Config란? [ Spring Cloud Config란? ] Spring Cloud Config는 분산 시스템에서 외부화된 설정 정보를 서버 및 클라이
mangkyu.tistory.com
https://docs.spring.io/spring-cloud-config/docs/current/reference/html/
Spring Cloud Config
Spring Cloud Config provides server-side and client-side support for externalized configuration in a distributed system. With the Config Server, you have a central place to manage external properties for applications across all environments. The concepts o
docs.spring.io
'Backend > MSA 전환' 카테고리의 다른 글
[MSA 전환하기 7편] 서킷 브레이커 적용하기 (Resilence4J) (1) | 2025.01.31 |
---|---|
[MSA 전환하기 6편] OpenFeign을 활용한 서비스 간 통신하기 (0) | 2025.01.29 |
[MSA 전환하기 4편] Spring Cloud Gateway 구현하기 (API Gateway) (0) | 2025.01.15 |
[MSA 전환하기 3편] Service Discovery 적용하기 (0) | 2025.01.13 |
[MSA 전환하기 2편] 멀티 모듈 구성하기 (0) | 2025.01.11 |