BackEnd/Spring Cloud

[Spring Cloud] Actuator๋ฅผ ์ด์šฉํ•œ Config Server ๊ธฐ๋™

ddonghyeo 2024. 1. 29. 19:26

0. Spring Cloud Config Server

MSA์™€ ๊ฐ™์€ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์—์„œ ๊ฐ ์„œ๋ฒ„๋“ค์˜ ๊ตฌ์„ฑ์— ํ•„์š”ํ•œ ์„ค์ •๋“ค์„ ์™ธ๋ถ€ ์‹œ์Šคํ…œ์—์„œ ํ•œ๋ฒˆ์— ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Spring Boot ๊ฐ™์€ ๊ฒฝ์šฐ๋Š”, ์„ค์ • ํŒŒ์ผ์ธ application.yml ๋˜๋Š” propertiesํŒŒ์ผ์ด ๊ทธ ๋Œ€์ƒ์ด ๋˜๊ฒ ๋‹ค.

 

Spring Cloud์˜ Config Server๋ฅผ ๊ธฐ๋™ํ•˜์—ฌ ์„ค์ • ํŒŒ์ผ๋“ค์„ ํ•œ๊บผ๋ฒˆ์— ๋ฌถ์–ด ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ํ•œ ์ €์žฅ์†Œ์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ณ , 

์„ค์ • ์ •๋ณด๋ฅผ ๋ฐ”๊พธ๋”๋ผ๋„ ๋‹ค๋ฅธ ์„œ๋น„์Šค๋“ค์„ ๋‹ค์‹œ ๋นŒ๋“œํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 

์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒฝ์šฐ, DEV์„œ๋ฒ„์™€ PROD ์„œ๋ฒ„๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ๊ฐœ๋ฐœํ•˜๊ธฐ๋„ ํ•˜๋Š”๋ฐ,

๊ฐ ์„œ๋ฒ„๋“ค ๋งˆ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ์„ค์ • ์ •๋ณด๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„์— ๋งž์ถฐ์„œ ๊ธฐ๋™ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

 

1.  Actuator

์•ž์—์„œ Config Server๋ฅผ ์ด์šฉํ•˜๋ฉด ์„ค์ • ์ •๋ณด๋“ค์ด ๋ณ€๊ฒฝ๋˜์–ด๋„ ์„œ๋ฒ„๋ฅผ ๋‹ค์‹œ ๋นŒ๋“œํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค๊ณ  ํ–ˆ๋‹ค.

 

๋ณดํ†ต์€ Spring Boot์˜ ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•  ์ˆ˜ ์žˆ๋Š” ํˆด์ธ Actuator๋ฅผ Refreshํ•จ์œผ๋กœ์จ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

์•„๋ž˜ ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์—ฌ๋Ÿฌ ์•ค๋“œํฌ์ธํŠธ๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html

 

Actuator๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด, client ์„œ๋ฒ„์— dependency๋ฅผ ์ถ”๊ฐ€ํ•˜์ž.

implementation 'org.springframework.boot:spring-boot-starter-actuator'

 

์ด์ œ client ์„œ๋ฒ„์˜ application.yml์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

- application.ym

management:
  endpoints:
    web:
      exposure:
        include: refresh

 

actuator์—์„œ ์—ด์–ด๋‘˜ ์•ค๋“œํฌ์ธํŠธ๋ฅผ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค. ์ผ๋‹จ์€ refresh๋งŒ ์„ค์ •ํ•ด๋‘๊ณ , ๋‚˜์ค‘์— ํ•„์š”ํ•  ๋•Œ ์ถ”๊ฐ€ํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.

 

๋งˆ์ดํฌ๋กœ ์„œ๋น„์Šค์—์„œ ์ด๋Ÿฌํ•œ Actuator๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด gradle์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋ฉด ๋œ๋‹ค.

dependencies {

   //Spring Boot Actuator
   implementation 'org.springframework.boot:spring-boot-starter-actuator'

}

 

ํ”„๋กœ์ ํŠธ์— Actuator๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค๋ฉด, ํ”„๋กœ์ ํŠธ์—์„œ Security ์ •์ฑ…์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด

actuator์™€ ๊ด€๋ จ๋œ uri๋“ค์€ ๋ชจ๋‘ permitAll ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

- SecurityConfig.java์˜ ์ผ๋ถ€

//...

http
   .authorizeHttpRequests(auth -> auth
      .requestMatchers("/actuator/**").permitAll()
      .anyRequest().authenticated()
   );
   
//...

 

์ด๋กœ์จ actuator์— ๋Œ€ํ•œ ์š”์ฒญ์€ ๋ชจ๋‘ ๋กœ๊ทธ์ธ์„ ๊ฑฐ์น˜์ง€ ์•Š์•„๋„ ๋  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ–ˆ๋‹ค.

 

ํ•ด๋‹น refresh ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๋ ค๋ฉด "IP์ฃผ์†Œ/actuator/refresh"๋กœ POST์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ๋œ๋‹ค.

 

 

 

2. profile์„ ์ด์šฉํ•œ ์„ค์ • ํŒŒ์ผ ์ด๋ฆ„

 

์—ฌ๋Ÿฌ ์„ค์ • ํŒŒ์ผ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์  ์ค‘ ํ•˜๋‚˜๋Š”, ์•ž์—์„œ ์–ธ๊ธ‰ํ–ˆ๋˜ dev์„œ๋ฒ„์™€ prod์„œ๋ฒ„๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ๊ฐœ๋ฐœํ•  ๋•Œ, ๊ฐ ์„ค์ • ์ •๋ณด๋“ค์„ ์—ฌ๋Ÿฌ ํŒŒ์ผ๋กœ ๋‚˜๋ˆ„๊ธฐ๋„ ํ•œ๋‹ค.

๋ณดํ†ต์€ dev, local, prod, test๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ ๋‚˜๋ˆ„์–ด์ง„ ์„ค์ • ํŒŒ์ผ๋“ค์€ default ์„ค์ •์—์„œ ์„ค์ •ํ•œ profile์— ์˜ํ•ด์„œ ๊ฐ ๋‹ค๋ฅธ ์„ค์ • ์ •๋ณด๋“ค์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด Spring Cloud Config Server๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ์–ด๋–ค ์‹์œผ๋กœ ๋„ค์ด๋ฐ์„ ํ•˜๋ฉด ์ข‹์„๊นŒ?

 

๋งŒ์•ฝ ์„œ๋น„์Šค๋“ค ์ค‘ user-service๋ฅผ ๊ธฐ๋™ํ•œ๋‹ค๊ณ  ํ•˜๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด ๋„ค์ด๋ฐ์„ ์ง€์œผ๋ฉด ๋˜๊ฒ ๋‹ค.

- user-service-prod.yml

- user-service-dev.yml

- user-service-local.yml

 

์ด๋Ÿฐ ์„ค์ • ํŒŒ์ผ๋“ค์˜ ๋„ค์ด๋ฐ๋“ค์„ ์ ์ ˆํ•˜๊ฒŒ ์ด์šฉํ•˜์—ฌ ํŒŒ์ผ๋“ค์„ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ  ์ ์šฉ์‹œํ‚ค๋ฉด ๋˜๊ฒ ๋‹ค!

 

3. Config Server

 

์ƒˆ๋กœ์šด Config Server ์—ญํ• ์„ ํ•ด์ค„ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , gradle์— ๋‹ค์Œ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

 

- build.gradle

ext {
	set('springCloudVersion', "2023.0.0")
}

dependencies {
	implementation 'org.springframework.cloud:spring-cloud-config-server'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}

 

ํ•ด๋‹น ์„œ๋ฒ„๋Š” Config Server๋กœ ๋™์ž‘๋  ์ˆ˜ ์žˆ๊ฒŒ @EnableConfigServer๋ฅผ ํ™œ์„ฑํ™” ์‹œ์ผœ์ค€๋‹ค.

 

- ConfigServiceApplication.java

@SpringBootApplication
@EnableConfigServer
public class ConfigServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigServiceApplication.class, args);
	}

}

 

์ด์ œ ์„ค์ • ํŒŒ์ผ๋“ค์„ ์„œ๋ฒ„์— ๋“ฑ๋กํ•ด ๋ณด๊ฒ ๋‹ค.

server:
  port: 8888

spring:
  profiles:
    active: prod
  application:
    name: config-service
  cloud:
    config:
      server:
        git:
          uri: https://github.com/DDonghyeo/spring-msa-yml

๋ณดํ†ต์€ ๊นƒํ—ˆ๋ธŒ์— private repository๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

 

private repository ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด ๋ณดํ†ต ๋น„๋ฐ€ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ssh๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.

ํ•ด๋‹น ๋‚ด์šฉ์€ ๋‹ค์Œ์— ๋‹ค๋ฃจ๊ธฐ๋กœ ํ•˜๊ณ , ์ง€๊ธˆ์€ public repository๋กœ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค.

 

- uri : ๊นƒํ—ˆ๋ธŒ ๋งํฌ

- search-paths : ํŒŒ์ผ ๊ฒฝ๋กœ

- default-label : ๋ธŒ๋žœ์น˜๋ช…

 

๊ธฐ๋™ ์ค‘์ธ Config Server์—์„œ ์„ค์ • ํŒŒ์ผ์ด ์ ์šฉ๋œ ํŒŒ์ผ์„ ๋ณด๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ ‘์†ํ•˜๋ฉด ๋œ๋‹ค.

http://localhost:8888/{ํŒŒ์ผ ์ด๋ฆ„}/{profile}

ํŠน๋ณ„ํ•œ profile์ด ์—†๋‹ค๋ฉด default๋กœ ์ ‘์†ํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.

 

๋‚˜๋Š” ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ • ์ •๋ณด ํŒŒ์ผ์„ ์„œ๋ฒ„์— ๋“ฑ๋กํ–ˆ๋‹ค.

 

4. Client Server

Config Server ์„ค์ •์„ ๋ชจ๋‘ ์™„๋ฃŒํ–ˆ๋‹ค๋ฉด, Client Server ์„ค์ •์„ ์•Œ์•„๋ณด๊ฒ ๋‹ค.

 

๋จผ์ € gradle์— ๋‹ค์Œ ์˜์กด์„ฑ๋“ค์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

 

- build.gradle

dependencies {

   //...

   implementation 'org.springframework.cloud:spring-cloud-config-client:4.0.3'
   implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap:4.0.3'

}

 

์ด์ œ ์ด client server์— bootstrap.yml ํŒŒ์ผ์„ ๋งŒ๋“œ๋Š”๋ฐ,

์ด bootstrap.yml์€ application.yml ํŒŒ์ผ๋ณด๋‹ค ๋” ๋†’์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ ธ ๋จผ์ € ์ ์šฉ๋œ๋‹ค.

์•ฑ์—์„œ ๊ฐ€์žฅ ๋จผ์ € ์„ค์ •๋˜๋Š” ์ •๋ณด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.

 

-bootstrap.yml

server:
  port: 9000

spring:
  cloud:
    config:
      uri: http://localhost:8888
      name: token

  application:
    name: user-service  # micro service unique ID

eureka:
  instance:
    instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
  client:
    register-with-eureka: true # register to eureka server
    fetch-registry: true # Getting instances' information from eureka server
    service-url:
      defaultZone : http://127.0.0.1:8761/eureka #Eureka Server's address

management:
  endpoints:
    web:
      exposure:
        include: refresh

 

User service์˜ actuator ์•ค๋“œํฌ์ธํŠธ refresh๋ฅผ ์—ด์–ด๋‘๊ณ , config server๋กœ๋ถ€ํ„ฐ name์ด token์ธ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

 

 

์„œ๋ฒ„ ๋กœ๊ทธ๋ฅผ ์‚ดํŽด๋ณด๋ฉด, config server๋กœ๋ถ€ํ„ฐ ์„ค์ • ์ •๋ณด๋ฅผ ์ž˜ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํ•ด๋‹น ์„ค์ •์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

https://docs.spring.io/spring-cloud-config/docs/current/reference/html/

 

Spring Cloud Config

Spring Cloud Config provides server-side and client-side support for externalized configuration in a distributed system. With the Config Server, you have a central place to manage external properties for applications across all environments. The concepts o

docs.spring.io

 

๋‚˜๋Š” ์ด๋ฅผ ํ™•์ธํ•ด๋ณด๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

@RestController
@RequestMapping("/user")
public class UserController {

    @Value("${jwt.secret}")
    private String secret;

    @GetMapping("/test")

    public String test() {

        return "token secret : " + secret ;
    }

}

ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ, ์„ค์ • ์ •๋ณด๋ฅผ ์ž˜ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

4. Actuator Refresh ํ…Œ์ŠคํŠธ

์ด์   ์„œ๋ฒ„๋ฅผ ๊ธฐ๋™ ์ค‘์—๋„ ์„ค์ • ์ •๋ณด๋“ค์ด ์ž˜ ๋ฐ˜์˜ ๋˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

๊นƒํ—ˆ๋ธŒ์— ์žˆ๋Š” ๋‚ด์šฉ์„ ๋ฐ”๊ฟ”์ฃผ์—ˆ๋‹ค.

 

์•„์ง์€ ์„œ๋ฒ„์— ๋ฐ˜์˜๋˜์ง€ ์•Š์•˜๋‹ค.

 

config server์—์„œ๋Š” ์ •์ƒ์ ์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.

 

POST์š”์ฒญ์„ ๋ณด๋‚ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—, postman์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

์„œ๋ฒ„IP/actuator/refresh๋กœ POST์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ๋œ๋‹ค.

 

 

์„œ๋ฒ„ ๋กœ๊ทธ์—์„œ config server๋กœ๋ถ€ํ„ฐ ์„ค์ • ์ •๋ณด๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๊ณ ,

๋ฐ”๋€ ๊ฒฐ๊ณผ ๋˜ํ•œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋Ÿฐ ๊ณผ์ •์„ ์ž๋™ํ™” ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด,

Github Action์„ ํ†ตํ•ด์„œ yml์ด ๋ชจ์—ฌ์žˆ๋Š” ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— push๋ฅผ ๊ฐ์ง€ํ•˜๋ฉด /actuator/refresh์— POST์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ณผ์ •์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค. ๐Ÿค”