일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- vm
- 배포
- Spring Security
- virtualization
- 스프링 부트
- spring batch
- 스프링
- spring cloud
- Spring
- 백엔드
- mysql
- 영속성 컨텍스트
- 스프링 시큐리티
- HTTP
- 자바
- 데이터베이스
- JPA
- 컨테이너
- Container
- 가상화
- 웹 서버
- spring boot
- ORM
- 도커
- CS
- 스프링 배치
- web server
- computer science
- Java
- CI/CD
- Today
- Total
개발 일기
[Spring Cloud] Spring Cloud Config Server - 2 (Spring Cloud Bus & RabbitMQ) 본문
[Spring Cloud] Spring Cloud Config Server - 2 (Spring Cloud Bus & RabbitMQ)
개발 일기장 주인 2025. 2. 11. 04:49https://ai-back-end.tistory.com/143
[Spring Cloud] Spring Cloud Config Server - 1
기존의 단일 프로젝트 멀티모듈 아키텍처에서는 GitHub Submodule을 사용하여 민감한 정보를 관리하고, 설정 파일이나 시크릿을 별도의 Private Repository로 분리하여 관리했다. 그러나 현재 마이크로서
ai-back-end.tistory.com
이전 게시글에서 Spring Cloud Config Server가 뭐하는 놈이고 어떻게 구성되어있으며 어떻게 동작하는지 알아봤다.
그런데 이때 Config Server를 이용하면 설정 정보들이 변경되어도 서버를 다시 빌드하지 않아도 된다는 장점이 있다고 했는데
/actuator/refresh를 통한 설정 정보 갱신
보통은 Spring Boot의 상태를 모니터링 할 수 있는 툴인 Actuator를 Refresh함으로써 정보를 가져올 수 있다.
흔히 쓰는 actuator 의존성을 추가한 후 POST /actuator/refresh를 하게되면
그러나 위의 경우 변경이 필요한 모든 Micro Service 들에 대해서 각각 모두 /actuator/refresh를 날려줘야한다.
그렇게 되면 서비스가 한두개면 괜찮은데 수 백개 그 이상 만큼 많다면 POST 요청이 그만큼 필요하게 된다.
그렇기 때문에 이때 Spring Cloud Bus라는 것이 도입됐다.
Spring Cloud Bus
Spring Cloud Bus는 분산 시스템에서 구성 변경 및 이벤트를 브로드캐스트할 수 있도록 도와주는 메시지 기반의 시스템입니다.
기존에는 각 마이크로서비스마다 개별적으로 /actuator/refresh 요청을 보내야 했지만, Spring Cloud Bus를 사용하면 한 번의 요청으로 전체 서비스에 변경 사항을 전파
- 설정 변경 (Update Config Info)
: 개발자가 Git 저장소에 있는 설정 파일을 변경 후 push. Git의 설정값이 업데이트됨. - 변경 알림 전송 (Notify Change Via Git Web Hook)
: Git Webhook이 Config Server의 /actuator/bus-refresh 엔드포인트를 호출. - 메시지 발행 (Publish Message) -> "RefreshRemoteApplicationEvent"
: Config Server가 Git에서 변경된 설정을 읽고, 메시지 브로커(RabbitMQ, Kafka 등)에 변경 사항을 전파.
이때, 변경된 설정에 대한 구체적인 정보를 담고 있는 것이 아니라, "설정이 변경되었음을 알리는 이벤트!!" - 설정 변경 알림 (Notify Services)
: 메시지 브로커가 각 마이크로서비스에 설정 갱신이 필요함을 알림. 변경된 설정을 구독하고 있는 모든 애플리케이션이 메시지를 수신.
Config Server → 메시지 브로커 (RabbitMQ/Kafka) → 각 클라이언트 서비스 (설정 변경 알림 수신) - 설정 반영 (Reload Config)
: 각 마이크로서비스가 Config Server에서 최신 설정을 가져와 반영. @RefreshScope가 적용된 Bean이 변경된 설정을 반영함.
각 클라이언트 서비스는 메시징 시스템을 통해 설정 변경 알림을 수신한 후, 해당 서비스는 Config Server로부터 최신 설정을 가진다.
// 의존성
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-bus-amqp'
}
// RabbitMQ 설치 및 연결
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
// actuator endpoint에 busrefresh 열어놓기
management:
endpoints:
web:
exposure:
include: busrefresh
// 테스트 용
test:
message: "Hello from Config Server!"
@RefreshScope
- @RefreshScope는 Spring Cloud Config와 함께 사용되는 어노테이션으로, 애플리케이션의 설정을 동적으로 갱신할 수 있도록 도와주는 기능을 제공한다.
- 이 어노테이션을 사용하면, 설정 값이 변경될 때 애플리케이션을 재시작하지 않고도 그 변화를 적용할 수 있다.
- @RefreshScope가 활성화되면, 해당 빈이 Spring의 컨텍스트에 로드될 때 초기값을 주입받고, Spring Cloud Config의 설정 값이 변경될 때마다 해당 빈이 갱신
- RefreshScope는 빈의 스코프를 prototype으로 설정하기때문에 해당 빈은 매번 새로운 인스턴스를 생성하여 반환하게 된다.
따라서 상태를 가지는 빈에는 주의가 필요!! - @RefreshScope가 적용된 Bean은 실제 Bean을 감싸는 프록시 객체로 생성ehlsek. 이때 Bean은 캐시(cache)에 저장되고, 이후에 실제 Bean이 호출될 때 캐시된 값이 사용한다.
설정값이 변경되면 빈을 Destroy하고 캐시 값도 초기화한다.
위 테스트용 같이 config server와 연결해둔 git repo의 store-application-local.yml파일에 설정파일을 올려 두고
테스트용 Config파일과 Controller를 만들어 둔 후 해당 컨트롤러로 curl을 찔러보면
설정 값이 정상적으로 들고 온 것을 알 수 있다.
이때 내가 궁금했던 것은 @RefreshScope + (@Value / @ConfigurationProperties)인데
@Value만 (without @RefresScope)
우선 위와 같이 RefreshScope를 주석처리해두고 /store/busrefresh를 해보겠다.
설정파일의 값을
다음과 같이 수정한 뒤 push했고
다음과 같이 /actuator/busrefresh (나의 경우 base url 설정을 해둬서 /store/busrefresh임) 해주고 curl로 설정 정보가 업데이트 됐는지 확인해보니 그대로였다.
비록 런타임 환경에서 TestConfig 빈이 변경된 설정 값을 바탕으로 새로 재등록되지는 않았지만, RabbitMQ 자체에는 /actuator/bus-refresh 요청이 정상적으로 전달되고 메시지가 브로커에 publish 된 것을 확인할 수 있었다.
즉, @Value의 경우 @RefreshScope를 달아줘야지 런타임 환경에서 빈이 변경된 사항을 바탕으로 빈을 재등록한다.
@Value + @RefreshScope
그래서 다시 TestConfig에 @RefreshScope를 달아주고 curl을 찔러보니 서버가 다운타임 없이 빈을 재등록하여 변경된 설정 값을 반환했다.
@ConfigurationProperties(prefix = " ") + @RefreshScope
ConfigurationProperties와 RefreshScope를 사용해도 정상적으로 런타임 환경에서 빈이 재등록 됐다.
@ConfigurationProperties(prefix = " ") (without @RefresScope)
이 또한 역시 @RefreshScope를 달아놓지 않아서 인지 변경사항이 반영되지 않았다.
'Back-End > Spring Cloud + MSA + Kubernetes' 카테고리의 다른 글
[분산 환경] 분산 환경에서 느슨한 결합을 위한 이벤트 기반 아키텍처 (0) | 2025.03.10 |
---|---|
[Kafka] 느슨한 서버 간 통신을 위한 Message Queue - Kafka (0) | 2025.02.11 |
[Spring Cloud] Spring Cloud Config Server - 1 (0) | 2025.02.10 |
[Spring Cloud] Spring Cloud Gateway & Spring Cloud LoadBalancer (0) | 2025.02.10 |
[Spring Cloud] Service Discovery를 위한 Spring Cloud Netflix Eureka (0) | 2025.02.09 |