Spring Cloud - Config Server
우선 Spring Cloud의 주요 컴포넌트를을 살펴보기 전에 12요소 어플리케이션
에서 대해서 간단히 짚고 넘어가보자.
12 요소 어플리케이션 (Twelve-Factor App)
클라우드 플랫폼이 어플리케이션 개발환경의 대세로 자리잡으면서 클라우드 플랫폼의 특징들을 잘 활용하도록 설계된 SaaS어플리케이션을 잘 만들기 위한 방법론을 의미한다.
핵심사상
선언적 형식을로 설정을 자동화해서 프로젝트에 새로 참여하는 동료가 적응하는데 필요한 시간과 비용을 최소화한다.
운영체제에 구애받지 않는 투명한 계약을 통해 다양한 실행 환경에서 작동할 수 있도록 이식성을 극대화 한다.
현대적인 클라우드 플랫폼 기반 개발을 통해 서버와 시스템 관리에 대한 부담을 줄인다.
개발과 운영의 간극을 최소화해서 지속적 배포를 가능하게 하고 애자일성을 최대화 한다.
도구, 아키텍처, 개발 관행을 크게 바꾸지 않도 서비스 규모의 수직적 확장이 가능하다.
Spring Cloud ?
Spring Cloud 는 위의 12요소 어플리케이션의 사상에 부합하는 Java 어플리케이션을 개발할 수 있도록 도와주는 광범위한 영역의 라이브러리들의 집합체이다.
그 중 Spring Cloud Netflix 를 구성하는 주요 컴포넌틀이다.
환경설정 외부화 담당 - 컨피그 서버
서비스 등록 및 탐색(discovery) - 유레카 서버
프록시 및 게이트웨이 역할 - 주울
마이크로서비스 자동등록 및 서비스 탐색의 구현
비동기 리액티브 마이크로 서비스 구성에 필요한 Spring Cloud Messaging
환경정보의 외부화, 컨피그 서버 - Config Server
일반적으로 Spring기반의 전통적인 웹어플리케이션을 개발할때 개발환경에 필요한 환경정보는 모두 프로젝트 소스내에 존재하는 application.properties 나 application.yml 파일로 관리한다.
소스와 정적 환경정보들의 분리차원에서 당연한 구조이겠으나, 현대의 어플리케이션들이 점덤 더 작은 단위의 어플리케이션으로 쪼개지면서 각 어플리케이션들의 환경설정을 담당하는 파일들도 서비스별로 분리되어 관리하기 더 어려워지게 되었다.
또한 예전보다 훨씬 더 어플리케이 환경의 변화주기가 빨라지는 상황에서 환경정보를 변경할 때마다 어플리케이션을 새로 빌드하고 배포해야 하는 구조는 분명 요즘의 클라우드 플랫폼기반의 개발환경에서는 한계가 존재한다.
스프링 클라우드의 컨피그 서버는 어플리케이션의 환경설정정보-특히 서비스,비즈니스 로직과 연관성이 있는 정보들-을 어플리케이션과 분리해 외부의 컨피그 서버를 통해 관리하도록 해준다.
각 어플리케이션의 환경설정 정보는 git 또는 SVN에 저장된다.
컨피그 서버는 git 서버에 접근해서 환경설정 정보를 읽어온다.
각 컨피그 클라이언트 (마이크로 서비스)는 컨피그 서버에 접근해서 환경설정 정보를 읽어온다.
컨피그 서버의 환경설정을 읽어오기 위한 정보는 bootstrap.properties가 담당한다.
컨피그 서버의 구성
컨피그 서버를 구성하기 위한 필수 의존성 라이브러리
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
스프링 엑추에이터는 필수 라이브러리는 아니지만 컨피그 서버 설정 후 Endpoing를 통한 컨피그 서버의 구성정보나 상태를 확인하기 위해서는 필요한 라이브러리이니 같이 추가하는게 좋다. 특히, 컨피그 서버를 바라보는 서비들은 환경설정의 변경상태를 재기동없이 읽어오기 위해서는 엑추에이터가 제공하는 Refresh Endpoint(/actuator/refresh)를 사용해야 하기 때문에 가급적 같이 추가하해서 사용하도록 하자.
스프링 클라우드 라이브러리는 기존 pom.xml에서 추가하는 경우라면, 스프링 클라우드 버전관리를 위한 아래의 설정정보도 같이 추가해야 한다.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
컨피그 서버도 상위개념인 Git서버를 참조해서 구동되어야 하기 때문에 bootstrap.properties파일이 필요하다.
컨피그 서버의 bootstrap.properties에 필수 설정값
server.port=8888
spring.cloud.config.server.git.uri=git서버위치
management.endpoint.env.enabled=true
management.endpoints.web.exposure.include=*
포트는 지정하지 않아도 디폴트로 8888로 지정된다.
스프링 액추에이터에서 제공하는 Endpoint를 모두 노출시켜 사용하길 원한다면 management.endpoints.web.exposure.include
값을 *
로 지정한다.
로컬에 Git을 구성할 경우, 아래의 의존성 라이브러리가 추가로 필요하다. 보통은 상용환경에서는 Github를 사용할 꺼라서 테스트에서만 사용하면 되는 라이브러리이다.
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.8.0.201706111038-r</version>
</dependency>
의존성 관리를 추가한 후, 정상확인하고 다시 제거하고 에러를 재현하려고 하였는데… 에러가 발생하지 않는다...
정확한 원인은 모르겠으나, 로컬에 구성한 Git 레파지토리에 스프링부트(컨피그 서버)가 최소에 접속할 때 필요한 라이브러리가 없어서 에러가 난게 아닐까 추측이 되고, 의존성 추가 후 정상 접속이 되고 어플리케이션도 정상 구동됨을 확인했다.
어플리케이션 환경설정 파일의 등록
컨피그 서버가 참조할 Git 레파지토리를 로컬에 구성하고, 테스트 목적으로 사용할 application.properties를 추가한다.
Git에 등록될 프로퍼티 파일은 디폴트 파일은 application.properties외에. 각 클라이언트 어플리케이션이 사용할 프로퍼티를 추가해서 사용하게 된다.
각 클라이언트 어플리케이션의 bootsrap.properties 프로퍼티 파일에서 지정한 spring.applicaton.name=서비스명
의 서비스명으로 프로퍼티 파일을 만들게 된다.
아래와 같이 클라이언트 어플리케이션의 설정정보를 구성하였다면, Git 레파지토리에 등록할 해당 어플리케이션의 프로퍼티 파일명은 supplier-service.properties
가 된다.
spring.application.name=supplier-service
spring.cloud.config.uril=http://localhost:8888
컨피그 서버의 구동
컨피그 서버, 즉 스프링 부트 어플리케이션을 구동하고 엑추에이터 Endpoint를 통해 컨피그 서버의 상태를 확인해 보자.
현재 컨피그 서버에 등록된 어플리케이션 환경설정 파일은 2개이다.
application.properties
supplier-service.properties
각 프로퍼티 정보에 접근하기 위한 URL 규칙이 있다.
http://localhost:8888/{서비스명}/{프로파일명}/{깃브랜치}
프로파일이 default이고 깃 브랜치가 master일 경우 둘 중 하나는 생략가능하다.
http://localhost:8888/supplier-service/default/master
http://localhost:8888/supplier-service/default
http://localhost:8888/supplier-service/master
즉, 이 세 개의 경로는 모두 동일하다.
접속하면 아래와 같이 프로퍼티의 설정정보를 json형태로 확인할 수 있다.
{
"name": "supplier-service",
"profiles": [
"default"
],
"label": null,
"version": "a92fa477117546fae78d51e15ae0c3428b723fd1",
"state": null,
"propertySources": [
{
"name": "file:///Users/ykjang/Dev/Project/config-repo/supplier-service.properties",
"source": {
"supplier.name": "supplier2"
}
},
{
"name": "file:///Users/ykjang/Dev/Project/config-repo/application.properties",
"source": {
"message": "helloworld"
}
}
]
}
프로파일은 별로로 지정하지 않았기 때문에 default
로 설정된다. 프로퍼티 파일을 위치와 이름, 소스내용들을 보여준다.
컨피그 클라이언트 구성
컨피그 클라이언트가 될 어플리케이션, 여기에서는 supplier-service 어플리케이션의 설정은 특별한 것 없다.
필요한 의존성 라이브러리 추가와 bootstrap.application파일의 설정이다.
필요 라이브러리
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
application.properties 을 bootstrap.properties파일로 변경하고, 필요한 설정정보들을 컨피그 서버의 Git 레파지토리에 있는 supplier-service.properties
파일로 옮긴다.
컨피그 서버 깃 레파지토리에 있는 supplier-service.properties
파일내용
supplier.name=supplier
어플리케이션 (컨피그 클라이언트)의 bootstrap.properties
파일내용
# 서비스명
spring.application.name=supplier-service
# 참조할 컨피그 서버 URL
spring.cloud.config.uri=http://localhost:8888
# 어플리케이션 구동 PORT
server.port=8090
management.endpoint.env.enabled=true
management.endpoints.web.exposure.include=*
컨피그 서버에 있는 supplier-service.properties
파일을 잘 읽어 오는지 테스트를 하기 위해, 컨트롤러 클래스와 간단한 API 메서드를 생성한다.
public class TestController {
"${supplier.name}" ) (
private String SUPPLIER_NAME;
"/supplier/name") (
public String getSupplyName() {
return this.SUPPLIER_NAME;
}
}
컨피그 서버의 깃 레파지토리에 있는 프로퍼티 파일의 속성값을 참조하도록 선언하고 메서드에서 해당값을 Return하도록 간단하게 구성하고 테스트를 해보자.
http://localhost:8090/supplier/name
을 호출했을때, supplier
라고 브라우저에 표시되면 정상적으로 컨피그 서버의 프로퍼티를 읽어온 것이다.
@RefrshScope
어노테이션에 대한 설명은 따로 포스팅을 하도록 하겠다.
최근댓글