Spring Cloud Config
Spring Cloud Config
Spring Cloud Config는 Spring 프레임워크 기반의 분산 시스템에서 설정 관리를 간편하게 하기 위한 도구이다. 여러 마이크로서비스가 함께 동작하는 환경에서 중앙화된 설정을 적용하고, 이를 외부에서 동적으로 수정할 수 있도록 지원한다.
- 중앙화된 저장소: 설정 정보는 외부 저장소에 저장되어 중앙화되며, 보통 Git과 같은 버전 관리 시스템을 사용한다. 이를 통해 변경 이력을 추적하고, 여러 환경에 대한 설정을 효과적으로 관리할 수 있다.
- 외부에서의 설정 관리: 서비스를 중지시키지 않고도 설정을 변경할 수 있다. 이는 서비스의 재시작 없이도 동적으로 설정을 갱신할 수 있어, 높은 가용성을 유지하면서도 설정을 최신 상태로 유지할 수 있음을 의미한다.
- 애플리케이션 배포 파이프라인 통합: 설정 정보는 애플리케이션 배포 파이프라인에서 통합되어, 개발, 테스트, 운영 등 다양한 환경에 대한 설정을 관리하기 용이하다.
- 서버-클라이언트 아키텍처: Config 서버는 설정 정보를 제공하고, 각 서비스는 클라이언트 라이브러리를 사용하여 이 정보를 가져와 자신의 설정으로 적용한다.
공식 문서: https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#_quick_start
Config Server
라이브러리
implementation("org.springframework.cloud:spring-cloud-config-server")
@EnablConfigServer
@EnableConfigServer
@SpringBootApplication
class ConfigServiceApplication
fun main(args: Array<String>) {
runApplication<ConfigServiceApplication>(*args)
}
application.yml
server:
port: 8888
spring:
application:
name: config-service
# 로컬 파일을 불러올 때
profiles:
active: native
cloud:
config:
server:
# 로컬 파일을 불러올 때
native:
search-locations: file://${user.home}/msa-study/git-local-repo
git:
# 로컬 깃에서 불러올 경우
uri: file://Users/kyoulho/msa-study/git-local-repo
# public Repository의 경우
uri: https://github.com/kyoulho/spring-cloud-config.git
username: [your username]
passwod: [your password]
# private Repsoitory의 경우
uri: git@github.com:kyoulho/spring-cloud-config.git
ignore-local-ssh-settings: true
private-key: |
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIIQf9VslUAT8vxL6sUBTaKuftWw7E6utoMcsdl4sl3/loAoGCCqGSM49
...
-----END EC PRIVATE KEY-----
# ssh-keyscan github.com의 hostmname
host-key: AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
# ssh-keygen -m PEM -t ecdsa -f 파일명
host-key-algorithm: ecdsa-sha2-nistp256
timeout: 4
파일 정보 확인
${서버 도메인}/${파일명}/${profile}로 접근한다.
// http://localhost:8888/ecommerce/default
{
"name": "ecommerce",
"profiles": [
"default"
],
"label": null,
"version": "2ea6bdf87a8474738cb312b1ecc193fcf913f5b2",
"state": null,
"propertySources": [
{
"name": "file://Users/kyoulho/msa-study/git-local-repo/ecommerce.yml",
"source": {
"token.expiration_time": 86400000,
"token.secet": "user_token",
"gateway.ip": "localhost:8000"
}
}
]
}
config client
라이브러리
bootstrap 라이브러리를 이용해서 설정 정보를 가져오던 방법도 있지만 org.springframework.cloud:spring-cloud-config-client 라이브러리를 사용하는 것을 추천한다.
implementation("org.springframework.cloud:spring-cloud-config-server")
application.yml
spring:
cloud:
# Spring Cloud Config에서 가져올 구성 파일의 이름을 지정
config:
name: ecommerce
# ecommerce-dev.yml을 찾는다. 존재하지 않을시 default를 가지고 온다
profile: dev
# 외부 구성 서버에서 구성을 가져오는 방법을 설정
config:
# optional 키워드는 구성 서버에서 구성을 가져올 수 없어도 애플리케이션이 계속 진행
import: optional:configserver:http://localhost:8888
부팅 시 로그
o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=ecommerce, profiles=[dev], label=null, version=e1bdcc51e12700a879c4e5f2d0888e97d72c5f3e, state=null
spring.cloud.config.profile 와 spring.profiles.active의 차이
spring.cloud.config.profile 은 가져올 구성 파일의 프로파일을 지정한다. 이 경우 "ecommerce-dev.yml"과 같은 프로파일별 구성 파일을 가져오게 된다.
spring.profiles.active은 애플리케이션에서 활성화할 프로파일을 지정한다. "dev"로 지정되어 있다면 application-dev.yml 파일이 활성화된다.
두 구성은 함께 사용될 수 있으며 첫 번째 구성은 Spring Cloud Config로부터 구성을 가져오고, 두 번째 구성은 애플리케이션의 활성 프로파일을 설정한다. 만약 두 구성을 함께 사용한다면, Spring Cloud Config에서 가져온 구성은 현재 활성화된 프로파일에 맞게 선택된다.
Actuator를 이용한 설정값 갱신
actuator를 사용하면 서버를 재기동하지 않아도 변경된 설정 정보를 가져올 수 있다. actuator의 refresh 엔드포인트를 이용하면 Environment로 가져온 정보는 갱신된다. Spring Security를 사용하고 있다면 /actuator/** 엔드포인트를 열어줘야 한다.
라이브러리
implementation("org.springframework.boot:spring-boot-starter-actuator")
application.yml
Actuator 엔드포인트 목록: https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints
# Spring Boot Actuator의 엔드포인트 노출을 구성합니다.
management:
endpoints:
# HTTP를 통한 엔드포인트 노출을 설정합니다.
web:
exposure:
# "*"는 모든 엔드포인트를 노출하도록 지정합니다.
include: "*"
Refresh
/actuator/refresh 엔드포인트는 애플리케이션의 런타임 환경에서 설정을 리로드 하고 갱신하는 역할을 한다. 이 엔드포인트를 호출하면 애플리케이션의 구성 속성이나 외부 구성 서버에서 가져온 설정을 다시 읽어 들이고, 새로운 값으로 갱신한다. /actuator/refresh를 호출하면, 설정이 변경된 빈(Bean)들이 다시 생성되고, @RefreshScope 어노테이션이 적용된 빈은 다시 초기화되어 외부에서 가져온 최신 설정값을 반영한다.
@RefreshScope
@Component
class EnvBean {
@Value("\${spring.datasource.username}")
lateinit var username: String
@Value("\${spring.datasource.password}")
lateinit var password: String
}