Config 서버
Config 서버는 분산 시스템에서 다수의 애플리케이션 환경 설정 정보를 중앙에서 관리하도록 하는 기능을 제공하는 환경 설정 서버이다.
이것은 서비스 및 비즈니스 로직과 관련된 정보를 애플리케이션으로부터 분리하고, 이를 외부에서 통합하여 관리하게 한다.
환경 설정 정보라 함은 데이터베이스 접속 정보, 미들웨어(연계서버) 접속 정보, 애플리케이션을 이루는 다양한 메타데이터를 포함하며,
이런 속성 값들은 일반적으로 application.properties 또는 application.yml 파일에 저장하여 사용하게 된다.
이렇게 중요한 정보들을 각 마이크로서비스가 각각 관리하게 될 경우, 환경 설정 값이 변경되면 모든 마이크로서비스를 다시 빌드하고 배포해야 하는 문제가 생기고, 특히 마이크로서비스의 수가 많을 경우, 변경 사항을 적용하는데 많은 시간과 노력이 필요하게 된다.
이런 문제를 해결하기 위해 Spring Cloud에서는 Config 서버라는 컴포넌트를 제공한다. Config 서버를 이용하면, 마이크로서비스의 환경 설정 파일을 한 곳의 중앙 서버에서 관리할 수 있게 되므로, 변경 사항을 적용하는데 필요한 노력과 시간을 크게 줄일 수 있게 된다.
위 그림과 같이 Config 서버가 구동될 때 Environment Repository에서 설정 내용을 가져온다. Environment Repository는 VCS, File System, DB로 구성 가능하다. 보통 Git이나 SVN같은 VCS를 많이 사용한다.
각 마이크로서비스들은 서비스가 구동될 때 Config 서버에서 설정 내용을 내려받아 애플리케이션이 초기화되고 구동된다.
만약 서비스 운영 중에 설정파일을 변경해야 할 경우에는 Spring Cloud Bus를 이용하여 모든 마이크로 서비스의 환경설정을 업데이트할 수 있다. Spring Cloud Bus는 각 서비스들간의 실시간 메시지 통신 역할을 하는 RabbitMQ 또는 Kafka 같은 경량 메시지 브로커들을 사용할 수 있도록 해주며, 이 메시지 브로커들을 이용하여 각 서비스들에게 Config 변경사항을 전파한다.
Config 서버 작성
의존성은 아래와 같이 추가해준다.
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2022.0.3")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-config-server'
}
tasks.named('test') {
useJUnitPlatform()
}
ConfigServer에서 다루는 파일들은 아래와 같다.
파일명 | 패키지명 | 구분 | 설명 |
build.gradle | / | 의존성 파일 | 의존성 관리 파일 |
application.properties | /src/main/resources | 리소스 파일 | SpringBoot 설정 |
templateSimple-dev.properties templatePortal-dev.properties templateEnterprise-dev.properties |
/src/main/resources/configuration-repository | 리소스 환경파일 | 애플리케이션 환경설정파일 |
ConfigServerApplication | com.msa.sample | 클래스 파일 | 애플리케이션 구동파일 |
yml vs properties
스프링부트로 프로젝트를 하다 보면, 리소스 파일이 application.properties 인 경우와 application.yml인 경우 두 가지가 있을 것이다.
사실 어떤 것으로 해도 상관 없지만, 나는 굳이굳이 properties 확장자를 사용한다. ( key-value 쌍이 더 편한거 같음 )
properties 특징
1. 키-값 쌍으로 구성되어 있다.
2. 형식이 매우 간단하고 직관적이며, 자바에서 널리 지원된다.
3. 정렬(들여쓰기) 할 필요가 없다.
단점 : 복잡한 계층 구조를 표현하기 어렵다
yml 특징
1. 계층 구조를 한눈에 보기 쉽게 표현 가능하다.
2. 데이터의 관계를 명확하게 표현할 수 있다.
3. 가독성이 매우 높다
단점 : 공백과 들여쓰기에 의존하기 때문에 실수로 오류를 만드는 데 더 쉽다.
ConfigServerApplication에 아래와 같이 @EnableConfigServer 어노테이션을 추가해준다.
다음 , application.properties 파일을 아래와 같이 작성한다.
server.port=8888
spring.application.name[0]=templateSimple
spring.application.name[1]=templatePortal
spring.application.name[2]=templateEnterprise
spring.profiles.active=native
#검색할 설정파일 경로
spring.cloud.config.server.native.search-locations=classpath:configuration-repository/
다음으로 환경파일을 작성한다.
(templateSimple-dev.properties, templatePortal-dev.properties, templateEnterprise-dev.properties)
생성할 디렉토리 위치는 아래와 같다.
//simple
config.profile=sht
config.message=templateSimple(dev)
Globals.DbType=postgresql
Globals.DriverClassName=org.postgresql.Driver
Globals.Url=jdbc:postgresql://localhost:5432/sht
Globals.UserName=jujonghun
Globals.Password=1234
//enterprise
config.profile=ebt
config.message=templateEnterprise(dev)
Globals.DbType=postgresql
Globals.DriverClassName=org.postgresql.Driver
Globals.Url=jdbc:postgresql://localhost:5432/ebt
Globals.UserName=jujonghun
Globals.Password=1234
//portal
config.profile=pst
config.message=templatePortal(dev)
Globals.DbType=postgresql
Globals.DriverClassName=org.postgresql.Driver
Globals.Url=jdbc:postgresql://localhost:5432/pst
Globals.UserName=jujonghun
Globals.Password=1234
그다음, 스프링부트 어플리케이션을 실행시고, localhost:8888/actuator로 서버가 정상적으로 실행되는지만 확인하고 바로 다음 단계로 넘어가보자.
Config 클라이언트 프로젝트 생성
ConfigClient 프로젝트 디렉토리 구조는 아래와 같다.
파일명 | 패키지 명 | 구분 | 설명 |
build.gradle | / | 의존성 관리 파일 | |
application.yml | /src/main/resources | 리소스 파일 | SpringBoot 설정 파일 |
bootstrap.yml | /src/main/resources | 리소스 파일 | SpringBoot 설정 파일(application.properties보다 우선적으로 적용되는 파일) |
ConfigClientApplication.java | com.msa.sample | 클래스 파일 | 애플리케이션 구동 파일 |
ConfigClientController.java | com.msa.sample | 클래스 파일 | 컨트롤러 파일 |
ConfigClientApplication.java 작성
아래와 같이 작성한다.
package com.msa.sample.configclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ConfigClientApplication {
public static void main(String[] args) {
String profile = System.getProperty("spring.profiles.active");
if(profile == null){
System.setProperty("spring.profiles.active","dev");
}
SpringApplication.run(ConfigClientApplication.class, args);
}
}
bootstrap.properties 파일 작성
server.port=9265
#서비스 ID(Config 클라이언트가 어떤 서비스를 조회할 것인지 매핑)
spring.application.name=templateEnterprise
#config 서버 url
spring.cloud.config.uri=http://localhost:8888
전자정부프레임워크에서는 bootstrap.properties 파일을 위처럼 작성하여 설정파일들 간에 우선순위를 두었지만. 최신 버전의 스프링 클라우드에서는 이를 권장하지 않는다. 또한, spring.cloud.config.uri를 사용하여 config서버를 연결하는 방법도 권장하지 않는다. bootstrap.properties 파일을 삭제하고 application.properties 파일을 아래와 같이 작성한다.
application.properties 파일 작성
그리고 actuator의 엔드포인트를 포함시키는 것에 대괄호를 포함시키면 에러가 발생한다.(위 캡쳐 참고)
ConfigClientController 클래스 작성
package com.msa.sample.configclient.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope
public class ConfigClientController {
@Value(value = "${config.profile}")
private String profile;
@Value(value = "${config.message}")
private String message;
@GetMapping("/config/profile")
public String profile() {
return profile;
}
@GetMapping("/config/message")
public String message() {
return message;
}
}
Config 클라이언트의 구동 및 테스트
config 클라이언트 서버를 실행하고 아래 url을 통해서 결과를 확인한다.
설정파일 (config 서버의 template-dev.properties 파일의 config.profile 값)의 내용이 정상 등록되었는지 확인하면 된다.
http://localhost:9265/actuator/env
ConfigServer에서도 콘솔 로그에 정상적으로 config가 전달되었는지 볼 수 있다.
Config 클라이언트 환경설정값 업데이트 테스트
Config Server의 다음의 환경파일에서 config.profile 속성정보를 ebt에서 ebt2로 변경한다.(변경하고 당연히 재실행 해야 함)
ConfigClient의 설정 정보를 갱신하는 요청을 보내도록 한다. 아래의 url을 post로 요청하여 변경된 속성 정보가 출력되는지 확인한다.(POST로 요청)
Linux, Mac의 경우 curl -X POST http://localhost:9265/actuator/refresh로 요청하여 결과를 확인한다. 변경된 속성 정보가 json 문자열로 출력되어야 한다.
DbType도 변경했다면 저 문자열에 Globals.DbType도 추가될 것이다.
'DEV > MSA' 카테고리의 다른 글
MSA 개발 가이드(9) - 마이크로 서비스 배포(Docker) (0) | 2023.06.27 |
---|---|
MSA 개발 가이드(8) - Spring Cloud Bus(RabbitMQ) (0) | 2023.06.27 |
MSA 개발 가이드(6) - Spring Cloud Gateway(Zuul) (0) | 2023.06.19 |
MSA 개발 가이드(5) - Spring Cloud Eureka(Service Registry) (0) | 2023.06.19 |
MSA 개발 가이드(4) - Resilience4j(Circuit Breaker) (0) | 2023.06.19 |