MSA 를 구성함에 있어서 스프링 클라우드 사용시 application.yml 파일의 수정이 자주 일어나게 된다.
해당 파일은 부트로 구성된 어플리케이션이 처음 로딩될 때 서버 정보에 반영되여 만약 수정이 일어나게 된다면
해당 프로젝트를 다시 실행해야 하는 번거로움이 생긴다.
그리고 각 마이크로서비스(이하 MS) 에서 사용되는 공통된 설정정보가 있을 경우
해당 공통 정보를 수정하게 될 때 , 각각의 MS 에 설정값을 모두 수정해 주어야 하는 번거로움이 있다.
이러한 불편함을 스프링 클라우드 에서 Config-Server 와 스프링 부트의 actuator 기능을 이용하게 된다면
서버를 재시작 하지않고 설정값 반영도 가능하고, 공통된 설정 정보를 관리할 수 있게 된다.
Config-Server
Config-Server 란 말 그대로 Config 정보를 관리하는 하나의 마이크로 서비스이다.
컨피스 서버에서 공통으로 관리할 설정정보(.yml 파일)을 등록하고, 다른 MS에서 해당 정보를 가져다 사용하는 방식이다.
스프링 클라우드의 bootstrap 라이브러리를 이용하여 다른 MS 가 구동될때 application.yml 을 읽기 전 Config-Server의 설정정보를 먼저 가져오게 만들수 있으며,
이러한 설정을 통해 여러 MS에서 공통으로 사용되는 설정정보를 Config-Server 하나로 관리 할수 있게 된다.
Config-Server 설정.
의존성추가하기
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
메인 포인트에 @EnableConfigServer 를 작성해 준다.
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
다음은 설정파일이다. 서버 정보와 공통으로 관리될 yml의 경로를 지정해준다.
application.yml (Config-Server 에서 사용되는 yml)
server:
port: 8888
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: file:///Users/choehyegeun/Desktop/msa/config-yml # 사용될 yml 파일 등록된 경로
git 을 이용하므로 해당 경로에 사용될 yml 을 git 에 등록시켜줘야 함 (현재 로컬에서만 사용하기 때문에 add, commit 만 진행)
사용된 ecommerce.yml
token:
expiration_time: 864000000
secret: my_token
gateway:
ip: ###.###.###.###
사용되는 마이크로 서비스 설정
User-Service
테스트 시나리오로 위에 Config-Server에 등록된 token정보로 User-Service의 JWT 토큰을 생성하려고 한다.
User-Service 안에 구현된 JWT 검증 필터 로직
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain,
Authentication authResult) throws IOException, ServletException {
String userName = ((User)authResult.getPrincipal()).getUsername();
UserDto userDetails = userService.getUserDetailsByEmail(userName);
String token = Jwts.builder()
.setSubject(userDetails.getUserId())
.setExpiration(new Date(System.currentTimeMillis()
+ Long.parseLong(env.getProperty("token.expiration_time"))))
.signWith(SignatureAlgorithm.HS512, env.getProperty("token.secret"))
.compact();
response.addHeader("token", token);
response.addHeader("userId", userDetails.getUserId());
}
여기서 사용되는 env.getProperty 값들을 Config-Server에서 가져와 사용하기 위해 다음과 같은 설정을 진행해 준다.
1. 의존성 추가
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
여기서 actuator 가 추가되었는데 해당 라이브러리는 User-service의 재시작 없이 설정 정보를 가져오기 위한 기능을 재공해준다.
actuator는 refresh, health, beans등 서버의 여러 설정을 서버 종료없이 확인하거나 갱신해주는 기능을 제공해 준다.
application.yml
## 나머지 설정정보 생략 ...
management:
endpoints:
web:
exposure:
include: refresh, health, beans
이제 Config-Server 의 정보를 어디서 가져올지 설정하는 bootstrap.yml 을 작성해준다.
위치는 application.yml과 동일한 위치에 생성하면 된다.
bootstrap.yml
spring:
cloud:
config:
uri: http://127.0.0.1:8888
name: ecommerce
여기서 uri는 현재 사용중인 Config-Server의 정보를 작성해 주고, name 아까 작성한 불러올 yml 파일의 이름을 작성해 준다.
테스트.
테스트를 위해 아까 위의 코드에서 env값을 확인하는 과정에서 인텔리제이의 DEUBG 모드를 이용하여 확인해 보겠다.
먼저 현재 설정된 값을 확인하기 위한 작업을 위해 User-Service에 로그인을 시도해 본다.
지금 설정된 값은 'my_token' 문자열로 작성되어 있다.
여기서 설정값을 'my_token_changed' 로 수정한 후 해당 서비스에 값을 반영시켜 보도록 하자.
ecommerce.yml 값 변경
token:
expiration_time: 864000000
secret: my_token_chagned
gateway:
ip: ###.###.###.###
변경된 정보를 이용하기 위해 actuator 의 refresh 기능을 사용해 준다.
사용 방법은 host:port/actuator/refresh 로 http POST 요청해주면 된다.
해당 url 요청시 변경된 값들이 반영되면서 string 형태로 리턴된다.
다시 로그인을 요청하면
아래와 같이 설정값이 변경된 것을 확인할 수 있다.
하지만 이러한 Actuator의 기능은 만약 여러 서비스의 변경이 필요하다면 각 서비스에 actuator/refresh 를 모두 요청해야 하는 번거로움이 또 생기게된다.
이러한 번거로움을 해결하기 위한 방법으로 스프링 클라우드 버스 를 이용하는 방법이 있다. 이는 다음 정리글로 남기려고 한다.
"본 포스트는 인프런에 Dowon Lee 님의 Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) 강의를 정리한 내용입니다."
댓글