[Spring Cloud] Config Server에 관하여 알아봅시다.

안녕하세요. 이경일입니다.
전부터 Spring Cloud Config서버에 관해서 정리를 하고 싶었는데 SpringCamp 2017 준비와 먹고사는 문제로 하지를 못했네요.

오늘 연휴를 맞아 Spring Cloud Config서버에 관해서 정리를 좀 해보려고 합니다.

What is Spring Cloud Config?

모든 Application은 설정이 필요합니다. DB주소와 접속 정보는 어떻고 연동할 Server의 주소는 뭐고 NoSql의 접속 정보 등등 아마 연차가 높으신 개발자 선배님들은 전에 이런 정보들을 소스코드에 하드코딩을 하고 필요할 때마다 주석을 풀었다 걸었다 하며 배포를 하던 시절을 경험하셨을 걸로 생각됩니다.

이러다가 Framework이 발전과 코드와 설정이 분리되어 만들자(?)라는 패러다임으로 application.properties 같은 환경에 따라 설정을 다르게 할 수 있는 방법이 나와서 지금도 많이 이용하고 있습니다.

따라서 이제는 환경별로 (local, dev, stage, real… 등등) 설정 파일을 분리하여 profile을 사용해 배포가 가능하게 되었죠. 하지만 이 방법에도 문제점은 있습니다. 설정 파일이 변경이 되면 다시 빌드&배포를 해야 한다는 점입니다.

또한 오늘날처럼 Traffic홍수의 시대에 더 이상 단일 Application으로는 이 Traffic을 감당하기가 어렵게 되었습니다.

서버의 규모가(클라우드 환경의 VM) 100대가 넘어가는 것이 일상처럼 되었습니다. (VM이 100대면 안에 Application은 더 많죠..) 이런 상황에서 동일한 Application에 다양한 환경으로 배포를 해야 하는 필요성이 생겼으며 이런 필요성을 효율적으로 관리하기 위해 해당 설정을 환경별로 중앙에서 관리를 해야 할 필요성이 생겼습니다.

Basic of Spring Cloud Server Architecture.

기본적인 구조를 설명하기 위해 위의 그림을 그려봤는데요. Spring Cloud Config의 경우 코드와 설정을 분리하기 위해 설정 파일들을 외부의 Git repository에 보관을 합니다. (코드와 설정의 분리는 Twelve factors 방법론을 참고하시면 좋을 거 같습니다.)

Spring Cloud Config Server의 경우 Git에 올라가 있는 properties, yml로 작성한 설정들을 내려주며 Spring Boot로 작성된 Application의 경우 bootRun시 해당 설정을 http로 받아서 에 사용하게 됩니다.

따라서 100개던 1000개던 동일한 환경과 설정으로 Application구동이 가능하여 설정을 중앙에서 관리를 할 수가 있으며 중요한 점이 Spring Cloud Server의 경우 설정을 Json으로 내려주고 있는 것입니다.

때문에 어떤 언어라도 해당 설정을 가져다 쓸 수 있습니다. 아마 이미 Open Source로 Client library 등이 나와있을 걸로 생각됩니다. (?)

참고로 Spring Cloud에서 또 중요한 모듈이 Service Discovery & Registry서버인 Eureka인데요 이 Eureka도 마찬가지로 Rest API 기반이라 다양한 언어에서 사용이 가능하며 Library도 많이 나와 있습니다. (?)

대중적인 Json포맷과 RestAPI를 지원한다는 점에서 Spring Cloud는 매우 유연한 Platform이라고 생각이 됩니다.

Micro Service Architecture로 구현 시에 꼭 동일 언어로 구현할 필요는 없습니다. 진정한 MSA를 위해서는 작은 Service와 해당 Service의 성격에 잘 맞는 언어를 사용하면 된다고 생각됩니다. 따라서 Spring Cloud Platform은 MSA를 구성할 때 그 중심점으로 사용하기에 적당하다고 생각이 됩니다.

How to use Spring Cloud Config?

일단 시작을 하기 전에 Git repository를 준비합니다. Public이던 Private이던 상관은 없습니다.

1. Create Spring Cloud Config Server

Spring Initializr에 접속합니다. (http://start.spring.io) “Search for dependencies”에 Config Server를 입력해서 선택을 해주면 위의 이미지처럼 “Selected Dependencies”에 들어오게 됩니다. 그 상태로 Generate Project 해주면 해당 프로젝트가 다운로드됩니다.

해당 프로젝트의 Application.java파일을 열고 @EnableConfigServer 에너테이션만 붙여주면 끝! 이 아니라 설정이 남았습니다.

2. Connect Git Repository with Spring Cloud Config Server

아까 처음에 만들어둔 Git repository를 연결해 보겠습니다.

Git repository 주소를 복사해서

application.yml 파일의 spring.cloud.config.server.git.uri 부분에 주소를 적으시면 됩며 Public Repository의 경우는 username과 password에 적지 않으셔도 됩니다.

(운영 서버에서는 ssh public key를 이용해서 접속하시면 됩니다.)

보통은 사내 Git Repository는 LDAP을 이용한 인증을 하는데요.  저는 실수로 username, password를 적고 git 에 push를 한 적이 있습니다. ㅜㅜ 하아… 제 정보를 몇 명이나 보았을지… 다른 분들은 조심하시기 바랍니다…

3. Create yml and Push to Git Repository

다음은 설정 파일을 환경별로 만드시면 됩니다.

  • dev : csclient-dev.yml
  • beta: csclient-beta.yml
  • real: csclient-real.yml
참고로 파일을 만드실 때는 {프로젝트명}-{환경명}.{yml 또는 properties}로 만드시면 됩니다.

안에 내용은 간단하게 Hello World로 보여드리기 위해…

이렇게 넣었습니다.

다음에 이 내용을 Git Repository에 Push 해주시면 됩니다.

이러면 Config Server사용 준비는 끝났습니다.

4. Spring Cloud Config Server bootrun and check config value

이제 bootrun을 합니다. 다음 실행이 완료되면 브라우저에 아래의 URL로 접속해 보시면 됩니다.

  1. http://localhost:8093/csclient/dev
  2. http://localhost:8093/csclient/beta
  3. http://localhost:8093/csclient/real

이렇게 우리가 yml로 설정했던 데이터가 Json으로 나오는 것을 볼수 있죠. 이걸로 Spring Cloud Config 서버 준비는 끝났습니다.

How to use Spring Cloud Config on Spring Boot Application?

이제 Spring Cloud Config서버를 Spring Boot Application에 연결하여 사용하는 csclient서비스를 만들어 보도록 하겠습니다.

Spring Cloud Config서버를 만들었던 것처럼 http://start.spring.io 에 접속해서 프로젝트를 만들도록 합니다.

config client와 web을 그리고 actuator와 view template로는 Freemarker 추가한 다음 Generage Project를 눌러서 프로젝트를 생성해 주시면 됩니다.

Project를 열고

bootstrap.yml파일을 추가한 뒤 이미지와 같이 config 서버 설정을 해줍니다.

bootstrap.yml파일은 spring cloud application에서 application.yml 파일보다 먼저 실행이 되기 때문에 config 서버의 설정을 써주면 bootrun 되기 전 Config Server에서 환경에 맞는 설정 파일을 불러와 실행이 되게 됩니다.

따라서 먼저 Build시에 application.yml보다 먼저 설정이 필요할 경우 bootstrap.yml에 설정을 해주면 됩니다. 그러면 이제 실행을 해보도록 하겠습니다.

그전에 아까 만들었던 설정파일 3개 기억 하고 계십니까?

  • dev : csclient-dev.yml
  • beta: csclient-beta.yml
  • real: csclient-real.yml

boot Application을 실행시킬 때 -Dspring.profiles.active={환경} 옵션을 같이 사용해 주셔야 합니다. 이렇게 실행을 시켜주면

제대로 실행이 된 것을 알 수 있습니다. 이제 Config 에 설정한 값을 이용해서 Hello World를 찍어 보도록 하겠습니다.

이제 csclient프로젝트에 Service를 2개를 만듭니다.

보면 Static, Dynamic 2가지 서비스입니다. 일단 둘 다 config server에서 데이터를 가지고와 출력해 주는 Service이지만 하나는 일반적인 Application처럼 처음 Build시에 정해진 값이 다시 빌드되기 전까지 바뀌지 않습니다. 하지만 Dynamic은 Config Server의 기능을 이용해 Dynamic 하게 재 빌드 없이 값이 바뀔 겁니다.

이제 코드를 보겠습니다.

먼저 ConfigServerTestStaticService 입니다.

코드에서 보다시피 아까 앞에서 config repository 에 저장했던 yml 파일에서 데이터를 꺼내와서 Map에 담아 리턴해 주는 단순한 코드입니다.

이제 ConfigServerTestDynamicService입니다.

ConfigServerTestStaticService와 달라진 것은 저 @RefreshScope가 달려있다는 것이죠. 저 에노테이션이 달려있는 Class는 config repository에 yml을 변경해 주면 Build 없이 자동으로 변경이 됩니다. (사실 완전 자동은 아닙니다… 이유는 뒤에서..)

마지막으로 이 2 서비스를 연결해줄 Controller를 만들도록 합니다.

ConfigServerTestController를 만들었습니다. 해당 Controller에서는 각 /config/static과 /config/dynamic을 각 서비스로 연결해주고 있습니다.

마지막으로 단순하게 map에 들어있는 값을 찍어주는 Freemarker view template를 만들었습니다.

 

이제 테스트를 해보도록 하겠습니다.

 

2가지 “/config/static”, “/config/dynamic“ 에 접속한 결과입니다.

csclient Application 빌드 시에 -Dspring.profiles.active=dev 옵션을 가지고 실행이 되었기 때문에 Config Repository에서 csclient-dev.yml 파일을 읽어와 Build

가 되었겠지요. 지금은 2 url의 결과가 보시다시피 같습니다.

이제 csclient-dev.yml 파일을 변경해 보도록 하겠습니다.

second 부분에 기존 Spring에서 Config Server로 변경하고 Git Repository에 Push를 해주었습니다.

Push 해주었으니 값이 바뀌겠지?라고 생각하실 수도 있는데요. 그러면 정말 좋은데 아쉽게도 아닙니다. 한 가지를 더 해줘야 하는데요.

이렇게 /refresh url로 Body는 빈 값으로 POST method를 이용해 호출을 한번 해줘야 합니다.

결과를 보면

/config/static은 그대로인데

@RefreshScope을 사용했던 /config/dynamic은 변경된 것을 보실 수 있습니다. 정말 쉽다고 생각하지 않으신가요?

제 개인적인 생각인데 아마 Spring Cloud Config서버를 개발했던 사람들은 충분히 Git Repository의 변경점을 감지해서 수동으로 빈 값 /refresh POST를 호출해 주지 않아도 충분히 자동으로 갱신을 시켜줄 수 있었겠지만. 아마 실수로 Push 하는 경우도 있어 (큰 프로젝트일수록 여러명이 작업을 할 테니) 사고를 방지하고자 이런 방식으로 한 것이 아닌가 생각합니다.

(각 서버별로 POST를 호출해 줄 때 그냥 for문에 넣고 동기로 호출해주면 갱신 대상 서버가 많을 경우 시간이 오래 걸립니다. SpringCamp 2017에서 toby님의 발표를 들으셨으면 아마 해결 방법을 알고 계실 것이라고 믿습니다. ^^)
이상으로 Spring Cloud Config 서버에 관해서 알아보았습니다.
정말 완전히 기본적인 사용법만 알아보았는데요 다양한 사용법과 활용법이 있으니 Spring Cloud Config Reference를 참고하시고 혹은 Google링을 해서 활용방법을 찾아보시는 것도 좋습니다. 아니면 저에게 문의를 주셔도 됩니다.
감사합니다.

[Spring Cloud] Config Server에 관하여 알아봅시다.”에 대한 2개의 생각

  1. 고건주

    Config 서버에 대해서 공부하고 있는데 너무 설명 잘해주셔서… 잘 공부하고 갑니다.
    감사합니다.

    응답

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다