
Spring Boot 에서는 설정값을 관리하기 위한 Configuration Bean 객체들을 생성하여 이용한다.
보통 해당 설정값들을 하드코딩하여 관리하기 보단 Spring Cloud Config, Spring Valult와 같은 외부 저장소에서 설정값을 저장하고,
서버가 실행될 때 설정값들을 읽어 Bean 객체들을 생성한다.
이렇게 외부 저장소에 설정값을 관리하면, 코드의 수정 없이 저장소의 설정값 변경 만으로 설정을 변경할 수 있다.
하지만 외부 저장소의 설정값 변경 만으론 서버가 실행될 당시 생성된 Bean 설정 객체들을 수정할 수 없다.
서버가 재기동 되어야만, 변경된 설정값을 통해 Bean 객체들이 재생성되어 설정 변경을 반영할 수 있다.
@RefreshScope란 서버의 재기동 없이 Bean 객체를 새로고침하기 적용하기 위해 사용되는 애노테이션이다.
사용 방법은 다음과 같다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
@Component
@RefreshScope
public class ValueRefreshConfigBean {
private String color;
public ValueRefreshConfigBean(@Value("${application.theme.color}") String color) {
this.color = color;
}
//put getter here
}
해당 애노테이션이 적용된 빈들은 빈 새로고침의 대상이 된다.
management:
endpoints:
web:
exposure:
include: refresh
yaml 설정을 통해 actuator의 refresh 엔드포인트를 활성화한다.
/actuator/refresh 엔드포인트에 POST 요청을 전송하면 @RefreshScope이 적용된 모든 빈들이 새로고침되어 재생성된다.
이 때, 외부 저장소로 부터 설정값을 읽어 생성되던 빈들은 최신의 설정값을 반영할 수 있게 된다.
이처럼 서버의 재기동 없이 설정값 변경을 동적으로 적용할 수 있다.
일반적으로 k8s 환경에서 서버들은 deployment 단위로 배포되며, 여러개의 파드에서 실행된다.
즉 각 Bean 객체들은 각 파드의 서버마다 존재하며, POST /actuator/refresh 에 보낸 새로고침 요청은 특정 파드에만 적용되는 것이다.
빈 새로고침 요청을 각 파드의 서버마다 전송하면 모두 새로고침 할 수 있지만, 파드의 특성상 IP 값이 동적으로 변경되고
Spring Cloud Discover와 같은 별도 discover 서버 없이는 각 파드의 동적인 IP를 관리할 수 없다.
이를 해결하기 위해 이용되는 것이 Spring Cloud Bus 이다.
Spring Cloud Bus란, MSA 환경에서 Kafka나 RabbitMQ와 같은 메시지 브로커를 이용하여 여러 인스턴스 간에 메시지를 브로드캐스팅 하는 프레임워크이다.
이 Spring Cloud Bus를 이용하여 멀티 파드에서 운영되는 서버의 Bean을 새로고침 할 수 있다.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
kafak를 메시지 브로커로 이용하는 의존성 추가(다른 메시지 브로커라면 다른 의존성)
spring:
application:
name: spring-cloud-bus-producer
cloud:
bus:
refresh:
enabled: true
env:
enabled: true
# kafka topic 설정
destination: {kafka-topic-name}
# kafka 서버 설정
kafka:
bootstrap-servers: {kafka-server-url}
# busrefresh 엔드포인트 활성화
management:
endpoints:
web:
exposure:
include: busrefresh
메시지를 생성하여 kafka에 적재하는 역할을 하는 서버이다.
kafka 서버의 URL과 topic을 지정하고, actuator/busrefresh 엔드포인트를 활성화한다.
spring:
cloud:
# kafka topic 설정
bus:
destination: {kafka-topic-name}
# kafka 서버 설정
kafka:
bootstrap-servers: {kafka-server-url}
kafka의 메시지를 listening 하다가, 특정 topic의 메시지를 consuming 하여 로직을 수행하는 서버이다.
@Component
@RefreshScope
public class ValueRefreshConfigBean {
private String color;
public ValueRefreshConfigBean(@Value("${application.theme.color}") String color) {
this.color = color;
}
//put getter here
}

- 외부 저장소에서 설정값을 변경한다.
- 메시지 Producer 서버에
POST /actuator/busrefresh요청을 전송한다.- 메시지 Producer 서버는 메시지 브로커인 Kafka에
RefreshRemoteApplicationEvent메시지를 적재한다.- Kafak를 listening 하고 있던 각 인스턴스(Clinet)는
RefreshRemoteApplicationEvent메시지를 consume 하여@RefreshScope이 적용된 모든 빈들을 새로고침한다.(필요에 따라 외부저장소 참고)