많은 개발자가 구성 정보를 저장하기 위해 저수준의 프로퍼티(property) 파일(yaml, json 또는 xml)로 전환할 것이다.
대개 이러한 프로퍼티 파일은 데이터베이스 및 미들웨어 접속 정보와 애플리케이션 행동 양식을 정하는 메타데이터가 존재하는 서버로 둔다.
애플리케이션을 프로퍼티 파일로 분리하는 것은 쉬우며, 대부분의 개발자는 구성 파일을 소스 관리 시스템에 넣거나 애플리케이션 일부로 배포하는 일 외에는 애플리케이션 구성을 위한 어떤 운영 작업도 하지 않는다.
배포되는 실제 코드에서 애플리케이션의 구성을 완전하게 분리한다.
서버 및 애플리케이션을 빌드하고 배포 환경에 따라 절대 바뀌지 않는 불변 이미지를 빌드한다.
서버를 시작할 때 환경 변수나 애플리케이션의 마이크로서비스가 읽어 올 수 있는 중앙 저장소를 이용해 애플리케이션 구성 정보를 주입한다.
마이크로서비스의 인스턴스는 사람이 최소한으로 개입해 신속하게 시작해야 하므로 클라우드에서 실행되는 마이크로서비스에 애플리케이션 구성 관리는 매우 중요하다.
분리 : 실제 물리적인 서비스의 배포와 서비스 구성 정보를 완전히 분리해야 한다.
추상화 : 서비스 저장소에 직접 엑세스하는 코드를 작성하기(즉, JDBC를 사용해 데이터베이스에서 데이터 읽기)보다 애플리케이션이 REST 기반의 JSON 서비스를 사용해 구성 데이터를 조회하게 만들어야 한다.
중앙 집중화 : 클라우드 기반의 애플리케이션에는 말 그대로 수백 개의 서비스가 존재할 수 있으므로 구성 정보를 보관하는 저장소 개수를 최소로 줄이는 것이 매우 중요하다.
견고성 : 애플리케이션 구성 정보를 배포된 서비스와 완전히 분리하고 중앙 집중화하므로 어떤 솔루션을 사용하더라도 고가용성과 다중성을 구현할 수 있어야 한다.
애플리케이션의 구성을 제대로 관리하지 못하면 탐지하기 어려운 버그와 예상하지 못한 장애를 만드므로 애플리케이션의 구성 데이터를 추적하고 버전을 제어하는 것은 아무리 강조해도 지나치지 않다.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId> ---- 사용할 스프링 클라우드 버전
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
<dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency> └ 이 서비스에 사용할 스프링 클라우드 프로젝트들
<dependency>
<groupdId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency> └이 서비스에 사용할 스프링 클라우드 프로젝트들
</dependencies>
<!--Docker build config-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>com.throughtmechanix.confsvr.ConfigServerApplication</start-class>
<java.version>1.8</java.version>
<docker.image.name>johncarnell/tmx-confsvr</docker.image.name>
<docker.image.tag>chapter3</docker.image.tag>
</properties>
</properties>
첫 번째 의존성은모든 스프링 클라우드 프로젝트에 사용되는 spring-cloud-starter-config다.
두 번째 의존성은 spring-cloud-config-server 스터터 프로젝트로 스프링 클라우드 컨피그 서버를 위한 핵심 라이브러리가 들어 있다.
컨피그 서버를 동작하게 하려면 여러 파일을 설정해야 한다. 우선 설명한 것은 application.yml 파일이며 confsvr/src/main/resources 디렉터리에 있다.
application.yml 파일에는 스프링 클라우드 컨피그 서비스가 수신 대기할 포트, 구성 데이터를 제공하는 백엔드 위치 등 정보를 명시한다.
┌스프링 클라우드 컨피그 서비스는 스프링 부트 애플리케이션이므로 @SpringBootApplication 에너테이션을 붙인다.
@SpringBootApplication
@EnableConfigServer ----@EnableConfigServer 애너테이션은 서비스를 스프링 클라우드 컨피그 (Spring Cloud Config) 서비스```
코드를 입력하세요
```로 사용 가능하게 한다.
public class ConfigServerApplication{
public static void main(String[] args){
SpringApplication.run(ConfigServerApplication.class, args);
}
}
스프링 클라우드 컨피그 서버는 confsvr/src/main/resources/application.yml 파일의 항목을 사용해 애플리케이션 구성 데이터를 보관할 저장소를 지정한다.
server :
port : 8888 --- 스프링 클라우드 컨피그 서버가 수신 대기하는 포트
spring :
profiles :
active: native --- 구성 정보를 저장할 백엔드 저장소 ( 파일 시스템)
cloud :
config :
server :
native :
searchLocations : file://Users/johncarnell1/book/
spmia_code/chapter3-code/confsvr/src/main/
resources/config/licensingservice --- 구성 파일이 저장된 경로.
import java.util.list;
import java.util.UUID;
@Service
public class LicenseService{
@Autowired
private LicenseRepository licenseRepository;
@Autowired
ServiceConfig config;
public License getLicense(String organizationId, String licenseId){
LicenseRepository.findByOrganizationIdAndLicenseId(organizationId, licenseId);
return license.withComment(config.getExampleProperty());
}
public List<License> getLicenseByOrg(String organizationId){
return licenseRepository.findByOrganizationId(organizationId);
}
public void saveLicense(License license){
license.withId(UUID.randomUUID().tostring());
licenseRepository.save(license);
}
}
스프링 클라우드 컨피그 서버의 백엔드 저장소로 파일 시스템이 적합하지 않은 이유는 개발 팀이 컨피그 서버의 모든 인스턴스에 마운트될 공유 파일 시스템을 설정하고 관리해야 되기 때문이다.
스프링 클라우드 컨피그 서버는 애플리케이션 구성 프로퍼티를 호스팅하는 다양한 백엔드 저장소와 통합될 수 있다.
깃을 사용하면 구성 관리 프로퍼티를 저장할 때 소스 관리의 모든 혜택을 누르고 빌드 및 배포 파이프라인에서 프로퍼티 구성 파일의 배포를 쉽게 통합할 수 있다.
application.yml
server :
port : 8888
spring :
cloud :
config :
server :
encrypt.enabled : false
git : ---- 스프링 클라우드 컨피그에 백엔드 저장소로 깃을 사용한다고 전달한다.
uri : https://github.com/klimtever/config-repo/ ---- 스프링 클라우드 컨피그에 깃 서버와 깃 repo의 URL을 전달한다.
searchPaths : licensingservice, organizationservice ---- 스프링 클라우드 컨피그에 구성 파일을 찾을 깃 경로를 전달한다.
username : native-cloud apps
password : 0ffended
세 가지 중요한 구성은 spring.cloud.config.server, spring.cloud.config.server.git.uri와 spring.cloud.config.server.git.searchPaths 프로퍼티다.
spring.cloud.config.server : 프로퍼티에서 스프링 클라우드 컨피그 서버에 파일 시스템 기반이 아닌 백엔드 저장소를 사용할 것이라고 알린다.
spring.cloud.config.server.git.uri : 프로퍼티는 접속할 저장소의 URL를 제공한다.
spring.cloud.config.server.git.searchPaths : 프로퍼티는 스프링 클라우드 컨피그 서버가 가동될 때 검색할 깃 저장소의 상대 경로를 전달한다.
: 스프링 부트 액추에이터는 @RefreshScope 애너테이션을 제공하므로 스프링 부트 애플리케이션을 제공하므로 스프링 부트 애플리케이션이 /refresh 엔드포인트를 사용해 애플리케이션 구성 정보를 다시 읽어올 수 있다.
@SpringBootApplication
@RefreshScope
public class Application{
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
@RefreshScope 애너테이션에 대해 두가지 사항을 유의하자.
스프링 클라우드 컨피그 서비스는 이 서비스를 사용하는 모든 클라이언트에 변경이 일어났다고 알려 주는 스프링 클라우드 버스라는 푸시 기반의 매커니즘을 제공한다. 스프링 클라우드 컨피그는 RabbitMQ 같은 미들웨어를 추가해야 한다.
( 변경을 감지하는 매우 유용한 방법이지만 모든 스프링 클라우드 컨피그 백엔드가 콘설 서버처럼 푸시 매커니즘을 지원하는 것은 아니다.
스프링 클라우드 컨피그는 중요한 프로퍼티를 쉽게 암호화할 수 있는 기능을 제공하며 대칭(공유 비밀 키 사용) 및 비대칭 암호화(공개 비공개 키 사용)를 모두 지원한다.
✔암화화 적용 단계
1. 암호화에 필요한 오라클 JCE.jar 파일을 내려받고 설치한다.
2. 암호화 키를 설정한다.
3. 프로퍼티를 암호화 및 복호화 한다.
4. 클라이언트 측에서 암호화하도록 마이크로서비스를 구성한다.
실행 중인 애플리케이션과 서버가 불변하고 여러 환경에 배포되는 어떤 서버도 수작업으로 구성하지 않아야 한다. 하지만 이 모델은 JAR나 WAR 파일처럼 애플리케이션 산출물과 프로퍼티를 고정된 환경에 함께 배포하는 전통적인 배포 모델과는 상충된다.