
해당 포스팅은 인프런에 "Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)" 강의를 기반으로 작성됐습니다.
포스팅의 모든 사진 자료는 해당 강의 출처임을 밝힙니다.
분산 시스템에서 서버, 클라이언트 구성에 필요한 설정 정보(application.yml)를 외부 시스템에서 관리할 수 있도록 해줍니다.
하나의 중앙화된 저장소에서 구성요소 관리가 가능합니다.
각 서비스를 다시 빌드하지 않고, 바로 적용이 가능합니다.
애플리케이션 배포 파이프라인을 통해 DEV - UAT - PROD 환경에 맞는 구성 정보를 사용합니다. 즉, 각 필요 환경에 따라 자유롭게 설정 정보를 변경 및 관리가 가능합니다.
💡 UAT(User Acceptance Testing)
소프트웨어 테스트의 마지막 단계로 출시 전 목표로 한 사용자가 직접 확인하고 평가할 수 있도록 하는 단계입니다.

private Git Repository에 설정 정보를(application.yml) 저장한 뒤 Spring Cloud Config Server를 통해서 각 마이크로 서비스로 설정 정보를 동적으로 전달해줍니다.

로컬 C:/ 드라이브에 git-local-repo 라는 디렉토리를 생성해줍니다.
내부에 ecommerce.yml 파일을 생성해준 뒤 Git을 초기화 해줍니다.
깃 레포지토리를 생성한 위치에 ecommerce.yml 파일을 생성해줍니다.
내부에 몇가지 설정들을 추가해줍니다.
$ cd 경로
$ git init
$ git add ecommerce.yml
$ git commit -m "커밋 메시지"
위 절차대로 수행해주면, 위에 생성했던 git-local-repo 라는 디렉토리에 git repository가 생성되고, 디렉토리 내 파일들이 형상 관리됩니다.

application.yml 파일의 naming에 따라 설정 정보를 적용하는 우선순위가 다릅니다.
application.yml : 일반 설정 파일
application-name.yml : ex) user-service.yml
application-name-<profile>.yml ex) user-service-dev.yml
이 때, 프로필명은 자유롭게 부여가 가능합니다. ex) test, dev, local 등등...
💡 Profile이란?
Spring profile은 배포 환경(Dev, Stage, Prod, …) 에 따라 자동으로 스프링 프레임워크 내 설정값에 대한 bean 주입을 각기 다르게 설정할 수 있도록 도와주는 역할.
| Priority | Property Location |
|---|---|
| High | calsspath 내부, .config 디렉토리에 위치한 application.yml |
| calsspath 내부, .config 디렉토리에 위치한 application-{profile}.yml | |
| calsspath 내부, application.yml | |
| calsspath 내부, application-{profile}.yml | |
| calsspath 외부, .config 디렉토리에 위치한 application.yml | |
| calsspath 외부, .config 디렉토리에 위치한 application-{profile}.yml | |
| calsspath 외부, application.yml | |
| Low | calsspath 외부, application-{profile}.yml |

server:
port: 8888
spring:
application:
name: config-service
cloud:
config:
server:
git:
uri: file:// 파일 절대 경로
Config Service 를 실행한 뒤,
localhost:8888/ecommerce/default 경로로 이동합니다.
다른 profile의 경로로 이동할 경우에는 ecommerce 뒤에 경로로 profile 명을 추가해주면 됩니다.

spring-cloud-starter-config
spring-cloud-starter-bootstrap

applicatio.yml 파일보다 우선순위가 더 높은 yml 파일입니다.
외부 설정 정보를 불러오기 위해서 로컬 application.yml 설정 정보보다 우선순위가 높아야 하므로, 이를 위해 bootstrap.yml 파일을 등록해줍니다.

application.yml 상에 token 정보는 주석처리 해줍니다.
@GetMapping("/health-check")
public String status() {
return String.format("It's Working in User-Service"
+", port(local.server.port) =" + env.getProperty("local.server.port")
+", port(server.port) =" + env.getProperty("server.port")
+", token secret =" + env.getProperty("token.secret")
+", token expiration time =" + env.getProperty("token.expiration_time")
);
}

위처럼 정상적으로 Config Service에 연결된 것을 확인할 수 있습니다.

웹 브라우저 상에서 health-check 경로 요청 시 다음과 같이 Config Service에 저장된 정보들이 출력되는 것을 확인할 수 있습니다.
💡 bootstrap.yml 우선순위
우선순위를 확인하기 위해서는 서버를 실행하여 콘솔창을 확인하면 됩니다. 다음과 같이 bootstrap에 명시된 정보를 제일 먼저 읽어옵니다.

위처럼 설정 정보를 수정한 경우, 이를 반영하기 위해 git commit을 해준 뒤 User Microservice를 재기동 해줘야 반영이 됩니다.
그런데 이 과정은 문제가 하나있습니다.
설정 정보는 매번 바뀔 수 있는 내용이 많습니다. 하지만, 변경사항이 발생할 때마다 마이크로 서비스를 재기동 해줘야 하는 점이 번거롭습니다.
설정 정보의 수정 부분을 반영하기 위한 방법으로는 3가지가 있습니다.
서버 재기동
Actuator refresh
Spring Cloud Bus 사용
저희는 이러한 서버의 재기동 대신에 다른 방식으로 설정 정보를 반영하도록 하겠습니다.
그 방법 중 하나가 Actuator refresh 입니다.
Spring Boot Actuator는 Application 상태를 모니터링하고, Metric 수집을 위한 Http End Point를 제공해줍니다.
💡 Metric(메트릭) 이란?
시스템, 프로세스, 제품 또는 서비스의 성능을 측정하는데 사용되는 측정 항목 또는 지표를 말합니다.
Actuator 사용을 위해서 다음과 같이 설정하겠습니다.
http.authorizeHttpRequests(auth -> auth
.requestMatchers(new AntPathRequestMatcher("/**"))
.access(new WebExpressionAuthorizationManager("hasIpAddress('211.43.109.67')"))
.requestMatchers(new AntPathRequestMatcher("/actuator/**")).permitAll() // 추가
.anyRequest().authenticated()
);
actuator 사용을 위해 prefix인 '/actuator'를 permitAll 해줍니다.

refresh : 수정된 설정 정보 반영
health : 애플리케이션 기동 여부 확인
beans : 애플리케이션에 등록된 빈 정보 조회

현재 Config Service에 저장된 설정 정보입니다.
기존에는 이를 수정하기 위해 설정 정보 변경 및 git에 반영 후 User Microservice를 재기동 해줘야 했습니다.
하지만, actuator에 refresh 기능을 사용하면 재기동 없이 수정된 설정 정보를 반영할 수 있습니다.

테스트를 위해서 Config Service에 저장된 설정 정보를 수정해줍니다.
그 다음 User Microservice에 health-check 를 통해 설정 정보를 확인했지만 변화가 없었습니다.

이제 Actuator를 활용하여 refresh를 수행하겠습니다.
refresh는 POST 요청을 통해서만 사용이 가능합니다.
따라서 postman을 사용하여 POST 요청을 진행하겠습니다.

설정 정보 수정 성공 시 다음과 같이 변경된 설정 요소를 반환해줍니다.


이처럼 서버 재기동 없이 Actuator의 refresh 기능을 사용하여 수정된 설정 정보를 반영해봤습니다.
spring-cloud-starter-config
spring-cloud-starter-bootstrap
spring-boot-starter-actuator
spring:
cloud:
config:
uri: http://localhost:8888
name: ecommerce
management:
endpoints:
web:
exposure:
include: refresh, health, beans, httptrace
Actuator에서 사용할 endpoint들을 설정해줍니다.
새롭게 등록한 httptrace는 사용하기 위해서 application에 bean을 수동으로 등록해줘야 합니다.
@SpringBootApplication
@EnableDiscoveryClient
public class ApigatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ApigatewayServiceApplication.class, args);
}
@Bean
public HttpExchangeRepository httpTraceRepository(){ // Spring Boot 3.X 버전 부터 HttpTrace -> HttpExchange 로 변경
return new InMemoryHttpExchangeRepository();
}
}
Actuator의 httptrace 엔드 포인트 사용을 위해서 다음과 같이 HttpExchangeRepository 클래스를 Bean으로 등록해줘야 합니다.
Spring Boot 3.x 버전부터 기존의 HttpTrace 에서 HttpExchange로 수정됐으니 참고 바랍니다.
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/user-service/actuator/**
- Method=GET,POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/user-service/(?<segment>.*), /$\{segment}
API Gateway를 거쳐 라우팅되어 Actuator에 접근하기 위해서 Route 설정을 추가해줍니다.
health


refresh




이번에는 Spring Profile을 활용하여 배포 단계마다 다른 설정이 가능하도록 분기를 만드는 과정에 대해서 알아보겠습니다.
우선, 일반 ecommerce.yml, ecommenrce-dev.yml, ecommerce-prod.yml 파일을 생성해줍니다.

그 다음으로 bootstrap에 profile 설정을 추가해줍니다.
spring:
cloud:
config:
uri: http://localhost:8888
name: ecommerce
profiles:
active: dev
포스트맨으로 테스트한 결과, dev 토큰이 설정된 것을 확인할 수 있습니다.

즉, 마이크로 서비스마다 프로필을 통해 다른 설정 정보를 등록할 수 있습니다.

GitHub Repository를 public으로 생성해줍니다.
private으로 생성 시 설정 정보에 github 계정 정보를 추가해줘야 합니다.
spring:
application:
name: config-service
cloud:
config:
server:
git:
uri: https://github.com/hyensukim/spring-cloud-config-test.git
# uri: file://C:/git-local-repo
# username: [username] - private repo 인 경우 설정
# password: [password] - private repo 인 경우 설정
로컬 파일경로에서 github repository 주소로 변경해줍니다.

$ git remote -v
$ git remote add origin 레포 주소
$ git remote -v
위에 명령어를 사용하여 local git과 Github의 Remote repo를 연동해줍니다.
설정 정보를 수정 후 Github로 push해주면, 해당 변경 사항이 각 서비스에 반영됩니다.

기존의 token.secret 값을 mytoken_dev#2로 수정했습니다.
스테이징 및 커밋 후 깃허브로 push 해줍니다.

Config Service를 호출한 결과, 정상적으로 값이 변경된 것을 확인할 수 있습니다.


이번에는 Secure File Storage 중 Native File Repository 방식으로 설정 정보를 저장하고 반영하는 방법입니다.
우선, 로컬에 native-file-repo 라는 명칭의 디렉토리를 생성해줍니다.
해당 디렉토리 안에 다음과 같이 3가지의 yaml 파일을 생성해줍니다.
application.yml
ecommerce.yml
user-service.yml
그 다음 아래와 같이 Config Service에 application.yml 파일을 수정해줍니다.
spring:
application:
name: config-service
profiles:
active: native
cloud:
config:
server:
native:
search-locations: file:///${user.home}/native-file-repo
위와 같이 설정해주면, 루트 경로를 기준으로 사용자 홈에 해당 디렉토리를 찾아서 설정 정보를 가져오게 됩니다.
다음과 같이 설정 정보를 브라우저에 불러오는 것을 확인할 수 있습니다.
