마이크로서비스 아키텍처(MSA)에서 설정 중앙화를 구현한 뒤 마주하는 가장 큰 고민은 "변경사항을 어떻게 모든 인스턴스에 즉시 반영할 것인가"이다.
인스턴스가 단 몇 개라면 각 서비스의 /actuator/refresh를 일일이 호출할 수 있겠지만, 수십 개로 늘어나는 순간 이는 운영상의 재앙이 된다. 호출 누락이 발생하면 어떤 인스턴스는 구버전 설정을, 어떤 인스턴스는 신버전 설정을 사용하는 불일치 현상이 발생하기 때문이다.
이러한 수동 작업의 한계를 극복하고, 단 한 번의 이벤트로 전체 시스템의 설정을 동기화하기 위해 도입하는 것이 바로 Spring Cloud Bus다.
1. 주요 특징 및 핵심 로직
Spring Cloud Bus의 핵심은 메시지 브로커를 활용한 '이벤트 브로드캐스트' 구조에 있다. 특정 서비스 인스턴스에 갱신 요청을 보내면, 해당 인스턴스가 메시지 브로커를 통해 이벤트를 발행하고 이를 구독 중인 모든 노드가 동시에 설정을 갱신하는 방식이다.

이 시스템을 지탱하는 세 가지 핵심 요소의 역할은 다음과 같이 명확히 구분된다.
- Spring Cloud Bus (이벤트 레이어) :
- 설정 변경 이벤트를 추상화하고 전파하는 신경망 역할을 한다.
- 내부적으로는 RemoteApplicationEvent를 사용하여 분산된 노드 간에 어떤 작업이 필요한지(예: Refresh) 정의한다.
- 이 레이어 덕분에 개발자는 개별 노드의 주소를 몰라도 전체 시스템에 명령을 내릴 수 있다.
- RabbitMQ (운반체/브로커) :
- Bus가 발행한 이벤트를 실질적으로 배달하는 우체부다.
- 특히 RabbitMQ의 'Fan-out' 교환기(Exchange) 방식을 활용하는데, 이는 특정 메시지를 연결된 모든 큐(Queue)에 복사하여 전달하는 방식이다.
- 이를 통해 모든 서비스 인스턴스가 동시에 변경 알림을 수신할 수 있게 된다.
- AMQP (통신 규약/프로토콜) :
- Advanced Message Queuing Protocol의 약자로, 애플리케이션과 브로커 사이의 '공용 언어'다. Spring Cloud Bus는 이
- AMQP를 준수하는 브로커(RabbitMQ 등)와 통신하며 메시지의 안정성과 호환성을 보장한다.
- 의존성에 spring-cloud-starter-bus-amqp를 추가하는 순간, Bus는 HTTP 직접 호출 대신 이 AMQP 기반의 메시징 시스템을 전송 수단으로 사용하게 된다.
🔍 설정 변경 전파의 4단계 메커니즘
- 이벤트 트리거 (Event Trigger) : 관리자가 Config 저장소(Git)의 값을 수정한 뒤, 연결된 서비스 노드 중 아무 인스턴스 하나를 골라 POST /actuator/busrefresh 엔드포인트를 호출한다.
중요한 점은 특정 서비스가 아닌 게이트웨이나 유저 서비스 등 버스에 연결된 어떤 노드라도 트리거가 될 수 있다는 사실이다. - 이벤트 발행 (Event Publishing) : 요청을 받은 노드는 Spring 내부에서 RemoteApplicationEvent를 생성한다. 이 이벤트에는 "설정을 갱신하라"는 메시지와 함께 이벤트를 보낸 주체, 그리고 수신 대상에 대한 정보가 담긴다.
이후 이 이벤트는 AMQP 프로토콜을 타고 연결된 메시지 브로커(RabbitMQ)의 특정 Exchange로 전송된다. - 메시지 전파 (Message Propagation) : RabbitMQ는 수신된 이벤트를 'Fan-out' 방식으로 처리한다. 이는 메시지를 복사하여 현재 Bus에 연결된 모든 큐(Queue), 즉 모든 서비스 인스턴스에게 뿌려주는 방식이다.
이 과정에서 메시지 브로커는 각 서비스의 IP 주소를 알 필요가 없다. 큐를 구독하고 있는 모든 노드가 동시에 메시지를 받게 되기 때문이다. - 로컬 갱신 (Local Refresh) : 각 서비스 인스턴스는 큐를 통해 전달된 이벤트를 수신한다. 이벤트를 확인한 서비스는 내부에 구현된 수신기를 통해 자신이 관리하는 Bean들 중 설정값 변경이 필요한 대상을 찾아낸다.
이후 내부적으로 /actuator/refresh를 직접 호출했을 때와 동일한 로직을 수행하여 최신 설정값을 메모리에 즉시 반영한다.
2. 상세 가이드 및 심층 분석
🔍 RabbitMQ vs Kafka: 메시지 브로커 선택
실무에서는 인프라 상황에 따라 RabbitMQ나 Kafka 중 하나를 선택하게 된다. 이번 실습에서 사용한 RabbitMQ는 메시지 전달의 신뢰성과 안정적인 라우팅에 강점이 있어, 설정 전파와 같은 관리성 이벤트에 매우 적합하다.
| 핵심 모델 | 메시지 브로커 (Consumer 중심) | 이벤트 스트리밍 (Producer 중심) |
| 주요 특징 | 메시지 전달 보장, 복잡한 라우팅 가능 | 초당 수십만 건의 고성능 처리, Pub/Sub |
| Bus 활용 | 설정 전파, 시스템 간 메시지 전달 | 대용량 로그 수집, 실시간 데이터 처리 |
🔍 시스템 구성 및 의존성 설정
모든 서비스(Config, User, Gateway 등)에 spring-cloud-starter-bus-amqp 의존성을 추가해야 한다. 이 의존성이 포함되면 Spring Cloud Bus가 RabbitMQ를 전송 수단으로 인식하게 된다.
설정 코드 (application.yml)
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
include: busrefresh # Bus 전파를 위한 엔드포인트 노출 필수
🔍 /refresh vs /busrefresh
가장 큰 차이는 **'영향 범위'**다. /actuator/refresh는 요청을 받은 단일 인스턴스의 메모리만 갱신하지만, /actuator/busrefresh는 연결된 모든 서비스 노드에 이벤트를 전파한다. 운영 환경에서는 실수 방지와 자동화를 위해 busrefresh를 기본 패턴으로 가져가는 것이 유리하다.

3. 실무 팁 및 주의사항
- 엔드포인트 보안: /busrefresh는 시스템 전체의 상태를 바꾸는 강력한 도구다. 운영 환경에서는 반드시 인증과 인가(Spring Security 등)를 적용하거나 내부 망에서만 접근 가능하도록 네트워크를 제한해야 한다.
- RabbitMQ 기동 확인: 이벤트가 전파되지 않는다면 가장 먼저 RabbitMQ 서버가 정상 기동 중인지, 포트(5672)가 열려 있는지 확인해야 한다. 의존성만 추가하고 브로커가 없으면 애플리케이션 기동 시 에러가 발생할 수 있다.
- 선택적 갱신: 가끔 특정 서비스군만 갱신하고 싶을 때는 /busrefresh?destination=user-service:**와 같이 목적지를 지정하여 전파 범위를 조절할 수 있는 기능을 활용하면 효율적이다.
4. 마무리
Spring Cloud Bus의 도입은 단순한 기능 추가를 넘어 MSA 운영의 패러다임을 '수동 호출'에서 '이벤트 기반 자동화'로 전환하는 중요한 분기점이다. RabbitMQ라는 든든한 운반체를 통해 복잡하게 얽힌 마이크로서비스들의 설정을 한 번에 다스릴 수 있게 되었다. 결국 분산 시스템의 복잡도를 해결하는 열쇠는 각 요소를 직접 제어하는 것이 아니라, 일관된 규칙을 가진 이벤트 시스템으로 묶어주는 데 있다는 점을 다시 한번 체감할 수 있었다.
'Spring > Cloud' 카테고리의 다른 글
| [Spring] MSA 서비스 간 통신의 진화: RestTemplate에서 FeignClient까지 (0) | 2026.04.29 |
|---|---|
| [Spring] 안전한 MSA 운영을 위한 필수 전략: 설정 정보 암호화 및 복호화 흐름 정리 (1) | 2026.04.24 |
| [Spring] MSA 설정 중앙화: Spring Cloud Config와 다중 프로필 전략 (0) | 2026.04.23 |
| [Spring] API Gateway와 User Service로 이해하는 JWT 인증 흐름 (0) | 2026.04.21 |
| [Spring] API Gateway부터 Service Discovery까지: Spring Cloud Gateway 전체 구조와 동작 흐름 (0) | 2026.04.15 |