프로젝트를 진행하면서 다양한 서비스의 프로젝트 환경 설정 정보를 Spring Cloud Config Server와 GitHub Repository를 이용해 중앙에서 관리하면 클라이언트의 환경설정 정보를 따로 수정할 필요 없이 한 번의 수정만 가능할 것 같아 도입하기로 결정했다.
각 서비스 환경과 서비스 별 개발, 테스트, 로컬 환경을 구분해 파일을 관리하기 위해서 GitHub Repository를 하나 생성한다.
해당 레포지토리에는 Yaml파일만 관리하는 용도로 사용한다.
각각의 환경 별 설정 파일을 구성해 업로드한다.
# 로컬 환경 DB 설정
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true
username: root
password: root
---
# 클라우드 환경 DB 설정
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://클라우드 공개 IP:3306/serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true
username: 클라우드 DB User 이름
password: 클라우드 DB User 패스워드
위에서 Configuration 파일을 관리하는 레포지토리를 통해서 파일들의 내용들을 엔드포인트에 따라 불러올 수 있다. (설명 수정 필요)
Gradle 패키지를 start.spring.io에서 만든다. Dependacny는 Spring actuator, Config Server 라이브러리를 추가한다.
프로젝트를 생성한 후 빌드한 뒤 application.properties (application.yml) 파일을 수정해준다.
yml파일 수정 중 Private Repository를 사용하게 되는 경우 추가적으로 환경설정을 해준다.
server:
port: 8088 # Spring Cloud Config Server 포트
spring:
application:
name: config-server # Confing Server 이름
cloud:
config:
server:
git:
# uri: https://github.com/jymaeng95/spring-cloud-config-repository.git # public Repository의 경우 각 환경 별 Yaml 파일을 관리하는 깃헙 주소
uri: git@github.com:jymaeng95/spring-cloud-config-repository.git # private Repsoitory의 경우 ssh 키 발급해서 사용
ignore-local-ssh-settings: true
# Private Repository의 경우 개인키를 설정에 업로드
private-key: |
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIIQf9VslUAT8vxL6sUBTaKuftWw7E6utoMcsdl4sl3/loAoGCCqGSM49
...
-----END EC PRIVATE KEY-----
host-key: AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= # ssh-keyscan github.com의 hostmname
host-key-algorithm: ecdsa-sha2-nistp256 # ssh-keygen -m PEM -t ecdsa -f 파일명
timeout: 4
# actuator 기본 설정
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
shutdown:
enabled: true
Yaml 파일을 수정해준 뒤 실제 프로젝트를 실행시키는 스프링 컨테이너에 @EnableConfigServer 애노테이션을 추가해준다.
package com.test.springcloudconfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer // Spring Cloud Config Server로 사용하겠다는 어노테이션
public class SpringCloudConfigApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudConfigApplication.class, args);
}
}
실행한 후 환경 설정 Yaml 파일의 이름을 엔드포인트로 호출해본다.
http://localhost:8088/config/local
엔드포인트로 호출한다.
호출이 성공하고 Github Repository의 config-local.yml 파일에 작성한 내용들을 잘 가져옴을 확인할 수 있다.
GET /{application}/{profile}[/{label}]
GET /{application}-{profile}.yml
GET /{label}/{application}-{profile}.yml
GET /{application}-{profile}.properties
GET /{label}/{application}-{profile}.properties
application.properties
(application.yml)파일에 정의한 spring.application.name
속성 값을 의미한다.application.properties
(application.yml) 파일에 정의한 spring.profiles.active 속성 값을 의미한다.Server가 잘 동작하는 것을 확인했으므로, 클라이언트 프로젝트를 생성해주자.
클라이언트 프로젝트를 생성할 때 “Config Client”, “ Spring web”, “Spring Boot Actuator” 의존성을 추가해서 생성해준다.
프로젝트를 생성해 빌드해준 뒤 application.properties(application.yml) 파일을 수정해준다.
spring:
application:
name: config # 어플리케이션 이름 = Github 레포지토리에서 관리하는 파일 애플리케이션 이름
profiles:
active: local # 애플리케이션 환경 = local, dev
config:
import: optional:configserver:http://localhost:8088 # import:optional:configserver사용 -> Spring cloud config server 주소
server:
port: 9001 # Spring Cloud Config Client 주소
# 클라이언트 코드에서 Actuator 설정
management:
endpoints:
web:
exposure:
include: "*"
application.yml 파일을 수정했다면, config Server가 Git Repository를 스캔해서 가져온 파일들을 애플리케이션 환경 엔드포인트에 맞게 잘 가져오는지 테스트를 해본다.
설정 정보를 가져와 필드에 넣어주기 위해서 LocalConfig 클래스를 생성해서 코드를 작성한다.
설정 정보를 불러오는 클래스에는 @RefreshScope
를 반드시 넣어준다. 해당 애노테이션은 Git Repository에 있는 Config 파일을 수정했을시 /actuator/refesh 엔드포인트를 호출함으로 써 변경된 설정 값을 갱신해주는 역할을 하는 Spring Actuator 애노테이션이다.
마지막으로, 엔드포인트 호출 시에 변수에 넣은 값들을 String 형태로 호출하기 위해 toString()메소드까지 추가했다.
package com.test.springcloudclient.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@RefreshScope // Config.yml 파일 변경 시 변경된 내용을 actuator를 통해 변경값을 갱신
@Component
public class LocalConfig {
// {application-profiles}.yml 에 정의한 내용을 해당 변수에 넣어줌
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
@Override
public String toString() {
return "LocalConfig{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
다음으로, Controller 클래스를 생성해 실제 필요 엔드포인트 호출 시 Spring Cloud Config Server를 통해 GitHub Repository에 있는 값을 제대로 가져오는지 확인해본다.
package com.test.springcloudclient.controller;
import com.test.springcloudclient.config.LocalConfig;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/service")
public class LocalController {
// Configuration 주입
private final LocalConfig localConfig;
// 생성자 주입
public LocalController(LocalConfig localConfig) {
this.localConfig = localConfig;
}
// /service/local 엔드포인트 호출 시 "config-local.yml에 정의한 내용 불러옴"
@GetMapping("/local")
public String loadLocalConfig() {
return localConfig.toString();
}
}
테스트를 위한 Config 파일과 Controller 클래스를 생성했다면 Config Server 와 Config Client를 실행해서 확인해본다.
http://localhost:9001/service/local
을 호출 했을 때 아래와 같이 파일에 입력한 설정정보를 가져오는 것을 확인할 수 있다.
마지막으로, 위에서 LocalConfig 클래스에 작성한 @RefreshScope
이 잘 작동하는지 확인한다.
Config Server 와 Config Client를 실행시킨 상태에서 GitHub Repository의 config yml 파일을 수정한 후 Git에 push 한다.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true
username: woi Refresh Scope Test !!!
password: wei Refresh Scope Success !!!
클라이언트 단에서 POST http://localhost:9001/actuator/refresh
엔드포인트를 호출해 갱신해준다.
다시 클라이언트에서 http://localhost:9001/config/local
을 호출 한 후 결과를 확인한다.
변경한 내용으로 잘 수정된 것을 확인할 수 있다.
[spring boot 설정하기 - 14] spring cloud config (1) 설정 및 테스트 소스 : https://otrodevym.tistory.com/entry/spring-boot-설정하기-14-spring-cloud-config-설정-및-테스트-소스?category=815039
Spring Cloud Config: 소개와 예제 : https://madplay.github.io/post/introduction-to-spring-cloud-config