마이크로서비스 아키텍처(MSA)를 채택한 애플리케이션에서는 여러 개의 독립적인 서비스가 서로 협력하여 전체 시스템을 구성합니다.
각 서비스는 자체적인 설정 파일 application.yml을 사용하여 다양한 의존성 설정과 구성 정보를 관리합니다. 이러한 설정 파일에는 데이터베이스 연결 정보, 서버 포트 번호, 외부 API 키 등 중요한 설정 정보가 포함됩니다.
서비스가 많아질수록 각 서비스의 설정을 관리하는 것은 점점 더 복잡해집니다.
서비스에 필요한 설정 정보나 데이터가 변경될 필요가 있을 때, 이 설정 파일을 수정하려면 해당 서비스를 다시 배포하거나 서버를 재시작해야 합니다. 이 과정에서 배포 중 문제가 발생하면 서비스 중단이나 시스템 불안정 등의 심각한 문제가 발생할 수 있습니다.
MSA 환경에서는 이러한 설정 변경을 중앙에서 효율적으로 관리하고, 각 서비스가 실시간으로 설정을 업데이트할 수 있는 방법이 필요합니다. 이를 해결하기 위해 Spring Cloud Config가 도입되었습니다.
Spring Cloud Config란❓
Spring Cloud Config는 분산 시스템 환경에서 중앙 집중식으로 애플리케이션의 설정을 관리하는 프레임워크입니다. 이 도구는 애플리케이션의 설정 정보를 중앙 서버에서 관리하고, 설정 변경을 실시간으로 반영할 수 있도록 지원합니다.
- 중앙 집중식 설정 관리
- 애플리케이션의 모든 설정을 중앙 서버에서 관리하고, 여러 애플리케이션과 서비스가 동일한 설정을 공유할 수 있도록 합니다.
- 설정 파일의 실시간 변경 감지
- 설정 파일의 변경 사항을 실시간으로 감지하고, 애플리케이션에 자동으로 반영할 수 있습니다.
- 이를 통해 설정 변경 시 재배포 없이도 신속하게 적용할 수 있습니다.
- 버전 관리와 히스토리 추적
- Git과 같은 버전 관리 시스템과 통합되어 설정 파일의 버전 관리와 변경 히스토리를 추적할 수 있습니다.
- 이를 통해 이전 설정으로 롤백하거나 변경 이력을 확인할 수 있습니다.
- 다양한 저장소 지원
- Git, 파일 시스템, SVN, JDBC 등 다양한 저장소에서 설정 파일을 불러올 수 있습니다.
- 이를 통해 애플리케이션의 요구에 맞는 저장소를 선택할 수 있습니다.
- 환경별 구성
- 애플리케이션의 환경별 설정을 분리하여 관리할 수 있습니다.
- 예를 들어, 개발, 테스트, 운영 환경에 따라 별도의 설정 파일을 사용할 수 있습니다.
쉽게 말해, Spring Cloud Config는 분산 시스템에서 여러 애플리케이션의 application.yml 파일을 하나의 중앙 집중식 저장소인 Config Server에서 관리할 수 있게 해주는 기술입니다.
이를 통해 모든 애플리케이션이 동일한 설정 정보를 공유하고, 설정 변경 시 중앙에서 관리할 수 있어 효율적이고 일관된 설정 관리를 할 수 있습니다.
Spring Cloud Config 설정
Spring Config Server 설정
1. 의존성 추가
dependencies {
implementation 'org.springframework.cloud:spring-cloud-config-server' //Server
implementation 'org.springframework.boot:spring-boot-starter-web'
}
2. 설정 파일 구성
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/your-repo/config-repo
application.yml 또는 application.properties 파일에 Config Server의 설정을 추가합니다.
3. Config Server 활성화
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
@EnableConfigServer 어노테이션을 추가하여 Config Server를 활성화합니다.
Spring Config Client 설정
1. 의존성 추가
// Gradle
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-config'
}
2. 설정 파일 구성
spring:
application:
name: my-config-client
cloud:
config:
discovery:
enabled: true
service-id: config-server
eureka:
client:
service-url:
defaultZone: http://localhost:19090/eureka/
클라이언트의 application.yml 파일에서 Config 서버의 설정을 정의합니다.
Spring Cloud Config 환경별 구성관리 - spring.profiles.active
Spring Cloud Config 서버는 환경별로 다른 설정 파일을 제공할 수 있습니다.
예를 들어, 개발 환경과 운영 환경을 위해 각각 application-dev.yml과 application-prod.yml 파일을 Git 저장소에 저장하여 환경별 설정을 관리할 수 있습니다. 이를 통해, 각 애플리케이션이 실행되는 환경에 맞는 적절한 설정을 자동으로 불러올 수 있습니다.
예를 들어, 개발 환경에서는 application-dev.yml 파일의 설정이 적용되고, 운영 환경에서는 application-prod.yml 파일의 설정이 적용됩니다.
spring.profiles.active(프로필)
Spring Boot 애플리케이션에서 프로필을 사용하여 환경을 구분할 수 있습니다.
application.yml 또는 application.properties 파일에서 spring.profiles.active 속성을 설정함으로써, 현재 활성화된 프로필에 따라 적절한 환경 설정을 로드할 수 있습니다.
예를 들어, 다음과 같이 application.yml 파일에 설정하면,
spring:
profiles:
active: dev
dev 프로필이 활성화되어 application-dev.yml 파일의 설정이 적용됩니다.
spring:
profiles:
active: local
local 프로필이 활성화되어 application-dev.yml 파일의 설정이 적용됩니다. 이렇게 함으로써 애플리케이션은 개발 환경과 운영 환경에서 각각 다른 설정을 자동으로 적용할 수 있습니다.
실시간 구성 변경
Spring Cloud Config 서버를 사용하면 설정을 중앙에서 관리하고 실시간으로 변경할 수 있습니다. 실시간 구성 변경을 반영하는 방법에는 여러 가지가 있습니다.
- Spring Cloud Bus
- Spring Cloud Bus는 메시징 시스템(예: RabbitMQ, Kafka)을 사용하여 여러 마이크로서비스 간에 설정 변경 사항을 전파합니다.
- 설정이 변경되면 , Spring Cloud Bus는 변경 사항을 메시지로 전송하고, 이를 통해 모든 관련 서비스가 변경된 설정을 자동으로 받아들이도록 합니다.
- 이는 대규모 분산 시스템에서 매우 유용하게 활용될 수 있습니다.
- 수동으로 /actuator/refresh 엔드포인트 호출
- Spring Boot Actuator의 /actuator/refresh 엔드포인트를 호출하여 애플리케이션의 설정을 수동으로 새로 고칠 수 있습니다.
- 이 방법은 특정 애플리케이션에서 설정을 즉시 업데이트할 때 유용합니다.
- 이 엔드포인트를 호출하면, Spring Cloud Config 서버에서 최신 설정을 가져와서 애플리케이션에 적용합니다.
- Spring Boot DevTools
- Spring Boot DevTools는 주로 개발 환경에서 유용하게 사용됩니다.
- 개발 중에 애플리케이션의 설정 파일을 변경하고, DevTools를 통해 자동으로 애플리케이션을 재시작하거나 설정을 새로 고칠 수 있습니다.
- 이를 통해 개발자는 설정 변경을 빠르게 반영할 수 있습니다.
- Git 저장소
- Spring Cloud Config 서버는 Git 저장소를 지원하여 설정 파일의 버전 관리를 쉽게 할 수 있습니다.
- 설정 파일이 변경되면 Git 저장소에서 자동으로 변경 사항을 감지하고, 해당 변경 사항을 중앙 집중식으로 관리할 수 있습니다.
- 이 방법은 설정 파일의 변경 이력을 추적하고, 필요한 경우 이전 버전으로 롤백할 수 있는 장점이 있습니다.
수동 엔드포인트 호출을 통한 실시간 구성 변경 동작 확인
Config - Server
Product - Service
config-repo
목표
목표는 Spring Cloud Config를 활용하여 구성 변경을 실시간으로 반영하는 과정을 확인하는 것입니다.
- Config Server 설정
- Config Server를 설정하여 애플리케이션의 중앙 집중식 구성을 관리합니다.
- Product 서비스 구성
- Product 서비스 가 Config Server로부터 설정을 가져오고, 이를 동적으로 반영할 수 있는지를 확인합니다.
- 실시간 구성 변경
- 설정 파일을 변경한 후, /actuator/refresh 엔드포인트를 호출하여 변경된 설정이 실시간으로 반영되는 과정을 확인합니다.
구성 요소
Eureka Server
- 역할
- 서비스 디스커버리 서버로, 다른 서비스들이 Eureka에 등록하여 서로를 발견하고 통신할 수 있게 합니다.
- 포트: 19090
Config Server
- 역할
- 중앙 집중식 구성 서버로, 애플리케이션의 설정을 외부 저장소(예: 파일 시스템, Git 등)에서 관리합니다.
- 포트: 18080
구성
- application.yml에서 설정된 spring.cloud.config.server.native.search-locations를 통해 설정 파일이 저장된 위치를 지정합니다.
- config-repo 폴더 내에 설정 파일들을 저장하여 환경별 설정을 제공합니다.
Product Service
- 역할
- 실제 제품 정보를 제공하는 서비스로, Config Server에서 설정을 받아와 애플리케이션에 적용합니다.
- 포트: 19083 (Config Server에서 설정된 포트)
구성
- application.yml에서 spring.config.import 속성을 사용하여 Config Server로부터 설정을 가져옵니다.
- ProductController에서 @RefreshScope 어노테이션을 사용하여 설정 변경 시 애플리케이션의 빈을 동적으로 갱신합니다.
- 실시간 구성 변경 확인
- Eureka Server 실행
- 서비스 등록 및 발견을 위해 Eureka 서버를 먼저 실행합니다.
- Config Server 실행
- Config Server를 실행하여 중앙 집중식 구성 관리를 시작합니다.
- Product에 전달할 yml 파일 설정
- product-service.yml
- product-service-local.yml
- Product에 전달할 yml 파일 설정
- Config Server를 실행하여 중앙 집중식 구성 관리를 시작합니다.
- Product Service 실행
- Product 서비스를 실행하여 설정을 동적으로 적용할 준비를 합니다.
- Product 엔드포인트 호출
- http://localhost:19083/product 엔드포인트를 호출하여 초기 메시지와 포트를 확인합니다.
- 설정 파일 수정
- product-service-local.yml 파일의 메시지를 수정하고 Config Server를 재시작합니다.
- 설정 갱신 요청
- Talend API Tester, POSTMAN 등을 사용하여 http://localhost:19083/actuator/refresh로 POST 요청을 보내 설정을 갱신합니다.
- 변경 사항 확인
- 다시 http://localhost:19083/product를 호출하여 설정 변경 사항이 실시간으로 반영되었는지 확인합니다.
- Eureka Server 실행
이제 서버를 실행해 보겠습니다.
Product 서비스의 application.yml 파일에서는 server.port를 0으로 설정했지만, 실제로 서버를 실행해 보면 포트가 19083으로 할당된 것을 확인할 수 있습니다.
이는 Product 애플리케이션이 실행될 때 Config 서버를 통해 설정 파일을 가져오고, 설정 파일에서 profiles를 읽어서 product-service-local.yml 파일을 로드하기 때문입니다.
따라서 최종적으로 Product 서비스는 product-service-local.yml에 정의된 대로 포트 19083에서 실행됩니다.
Talend를 통해 메시지를 확인해 보겠습니다.
http://localhost:19083/product를 호출하면 PORT: 19083, message: product-service-local message가 반환됩니다.
애플리케이션이 실행될 때 Config 서버를 통해 설정 파일을 가져왔으며, 설정 파일의 profiles를 참조하여 local.yml 파일이 로드된 것을 확인할 수 있습니다. (local 프로파일이 적용된 상태입니다.)
그러면 만약 product의 application.yml에서 spring.profiles.active를 주석 처리하면 어떻게 될까요?
이 경우, Product 애플리케이션은 0번 포트가 아닌 19093번 포트로 실행되는 것을 확인할 수 있습니다.
이는 profiles가 주석 처리되었으므로, 기본 설정 파일인 product-service.yml이 로드되어 포트가 19093으로 설정되기 때문입니다.
Talend를 통해 확인해 보면, 설정 파일에서 message 값이 "product-service message"로 반환되는 것을 볼 수 있습니다.
19093으로 요청하면 위와 같이 -endfix가 붙지 않은 yml파일로 들어가서 메시지가 product-service-local이 아닌 메시지로 나옵니다.
그럼 이제, 메인인 Config Server에서 메시지를 변경한 후, Product 애플리케이션에서도 메시지가 함께 변경되는 모습을 확인해 보겠습니다.
현재는 http://localhost:19083/product로 요청하면 포트 19083과 메시지 "product-service-local message"가 반환됩니다.
이제 Config Server에서 product-service-local.yml 파일의 메시지를
"product-service-local message" ➡️ "product-service-local message update"로 변경한 후, Config Server 애플리케이션을 재시작해 보겠습니다.
이후에 /actuator/refresh 엔드포인트를 호출하여 설정 변경을 적용한 후, 다시 http://localhost:19083/product를 요청하여 갱신된 메시지가 반영되었는지 확인해 보겠습니다.
"http://localhost:19083/actuator/refresh"로 호출해 보면, 위와 같이 응답으로 message라는 키가 포함된 데이터를 확인할 수 있습니다. 이는 설정 파일의 메시지가 성공적으로 갱신되었음을 의미합니다.
그러면 이제 다시 한번 "http://localhost:19083/product" 요청을 보내면, 응답에서 메시지가 "product-service-local message update"로 변경된 것을 확인할 수 있습니다. 이를 통해 yml 파일의 메시지가 성공적으로 업데이트된 것을 확인할 수 있습니다.
@RefreshScope
@RefreshScope는 Spring Cloud의 어노테이션으로, 설정 변경 사항을 동적으로 반영할 수 있게 도와줍니다.
이 어노테이션을 사용하면 애플리케이션이 실행 중일 때 설정 값이 변경되면, 해당 설정 값이 반영되도록 빈을 자동으로 갱신할 수 있습니다.
- 빈의 동적 업데이트
- @RefreshScope가 적용된 빈은 설정 값이 변경될 때 자동으로 갱신됩니다.
- 이는 /actuator/refresh 엔드포인트를 호출하여 설정이 변경되었을 때, 빈이 새로운 설정을 반영하도록 합니다.
- 빈의 초기화
- 기본적으로 Spring 애플리케이션은 시작할 때 빈을 초기화하고, 설정 값이 변경되더라도
해당 빈은 갱신되지 않습니다. @RefreshScope를 사용하면 설정이 변경될 때 빈을 새로 생성하거나 업데이트하여 최신 설정을 반영할 수 있습니다.
- 기본적으로 Spring 애플리케이션은 시작할 때 빈을 초기화하고, 설정 값이 변경되더라도
- 용도
- 주로 외부 구성 파일이나 중앙 구성 서버에서 설정 값을 가져오는 경우 유용합니다.
- 예를 들어, Spring Cloud Config Server와 함께 사용할 때, 애플리케이션의 설정을 변경하고 싶을 때 @RefreshScope를 통해 설정 값의 변경 사항을 실시간으로 반영할 수 있습니다.
'Framework > Spring\Spring boot' 카테고리의 다른 글
[Spring Cloud] Zipkin을 이용한 분산 추적: 요청 흐름과 성능 모니터링 (0) | 2024.08.07 |
---|---|
[Spring Cloud] Spring Cloud Sleuth(분산 추적)와 Zipkin이란 ❓ (0) | 2024.08.07 |
[SpringCloud] JWT 토큰을 통한 Spring Cloud Gateway 인증 및 권한 관리 (0) | 2024.08.05 |
[Spring Cloud] Spring Cloud Gateway로 MSA 환경에서의 효율적인 요청 처리와 로드 밸런싱 구현하기 (0) | 2024.08.03 |
[Spring Cloud] Resilience4j를 활용한 서킷 브레이커의 상태 변화와 Fallback 메커니즘 (0) | 2024.08.03 |