management: endpoints: web: exposure: include: -"*"# (4) # - "refresh" # 위 '*' 으로 전체를 공개 해서 주석 # - "bus-refresh" # 위 '*' 으로 전체를 공개 해서 주석 endpoint: refresh: enabled:true
(1): 애플리케이션 이름을 지정 spring.application.name 값을 기준으로 Config Repositroy 저장소에 있는 Config 파일을 인식해서 가져오기 때문에 반드시 두 값을 일치 시켜야 합니다.
spring.application.name=order-service의 경우 order-service-{evn}.yml을 Config 파일로 인식함
(2): 변경사항을 전파하는 카프카 주소 작성
(3): Config Server 주소 작성, optional:configserver:{address}으로 작성
(4): actuator의 속성을 *으로 전체 공개, 실제 운영 애플리케이션에서는 필요한 부분만 공개해야 합니다.
Config Server 저장소 Gtihub Repository에는 위와 같은 yml이 구성되어 있습니다.
애플리케이션 구동
spring.application.name=order-service, profile=local 설정인 애플리케이션 구동했을 때는의 경우로 설명드리겠습니다. 애플리케이션이 구동할 때 Config Server에게 자신의 Config 설정을 가져옵니다. 위 이미지에서는 1, 2번 항목에 해당합니다. 자세히 코드 레벨로 살펴보겠습니다.
서버가 구동하면 /{name}/{profiles:.*[^-].*} API를 호출합니다. 해당 API 코드는 아래와 같습니다.
Config 서버를 통해서 가져온 값이 정상적으로 order application에 가져온 것을 확인할 수 있습니다.
Config Server를 통해해서 가져온 Confg 값을 다시 살펴보겠습니다. message.profile=local은 정상적으로 가져온 것을 확인할 수 있으며, local 프로필에는 message.server-name값이 없기 때문에 해당 값은 default config인 order-service.yml값의 message.server-name=Config Server의 설정값을 사용합니다. 즉 default 값도 확인해야 하기 때문에 profile, default profile을 조회합니다.
재시작 없이 Config 변경
Config Server의 가장 큰 장점 중 하나는 서버가 재시작 없이 Config 설정 파일을 바꿀 수 있다는 점입니다. 해당 기능에 대해서 살펴보겠습니다.
actuator 설정을 통해서 공개된 refresh API를 통해서 애플리케이션 구동 중에 Config 설정을 변경할 수 있습니다.
GET http://192.168.0.5:8585/orders/profile을 호출해보면 본인 설정보다 Config Server 설정이 우선되는 것을 확인할 수 있습니다. 해당 설정을 로컬에도 가지고 있는 경우에는 이 점을 유의해야 합니다.
서버가 여러대의 경우 Cloud Bus
일반적으로 서비스 인스턴스들은 2대 이상으로 구성하게 됩니다. 그러기 때문에 /actuator/refresh 호출을 인스턴스 수에 따라서 N 번 해야 하며, 컨테이너 환경에서는 해당 작업은 더 복잡합니다. 이러한 문제는 Spring Cloud Bus를 이용해서 Kafka으로 브로드캐스팅 방식으로 변경사항을 모든 인스턴스에게 전달하는 방식으로 해결할 수 있습니다.
메시지 플랫폼으로는 spring-cloud-starter-bus-amqp, spring-cloud-starter-bus-kafka을 선택할 수 있습니다. bus-amqp는 Rabbit MQ를 사용하고, kafka는 Kafka를 사용합니다. 본 예제는 Kafka를 기준으로 설명드리겠습니다.
위에서 구성한 카프카 설정, actuator으로 bus-refresh을 노출시키는 설정을 완료합니다. 해당 설정을 완료했다면 인스턴스를 2대를 각각 다른 포트로 애플리케이션을 구동시킵니다.
포스팅에서는 Eureka를 통해서 order-service를 랜덤 포트를 이용해서 2대를 구성했습니다. 포트가 각기 다르게 profile local으로 띄우기만 하면 되니 굳이 유레카에 해당 서버를 등록시킬 필요는 없습니다. 인스턴스가 2개를 띄웠다는 부분을 표시하기 위해서 이미지를 첨부했습니다.
각각 서버에서 /orders/profile을 호출해서 message.profile를 확인해보겠습니다.
59013 서버에 이벤트를 반영했지만 58704 서버에도 해당 내용이 전파된 것을 확인할 수 있습니다.
이벤트 확인
카프카 로그를 보면 정상적으로 이벤트가 발행된 부분을 확인할 수 있으며, 위에서 지정한 토픽 이름인 ${spring.application.name}config-bus-refesh-event을 확인할 수 있습니다. 만약 코드 레벨에서 Config 변경 이벤트 구독 받아 후속 작업을 하고 싶은 경우에는 @EventListener으로 RefreshRemoteApplicationEvent 이벤트를 구독 받아 처리할 수 있습니다.