๋ชฉ์ฐจ
- Spring Cloud Config: ์๊ฐ์ ์์
- Spring Cloud Config: Spring Cloud Bus ์์
- Spring Cloud Config: Git Webhook์ ์ด์ฉํ ์๋ ๊ฐฑ์
- Spring Cloud Config: Spring Boot 2.4 ๋ฒ์ ์์์ ๋ณ๊ฒฝ์ฌํญ
Spring Cloud Bus๊ฐ ์ ํ์ํ ๊น?
์์ ๊ธ์์๋ ์คํ๋ง ์ค์ ์ด ๋ฐ๋์์ ๋ ๋ฐฐํฌ ์์ด ๊ฐฑ์ ํ ์ ์๋๋ก ํ๋ Spring Cloud Config๋ฅผ ์ ์ฉํ์๋ค.
๊ทธ๋ฐ๋ฐ ํด๋ผ์ด์ธํธ์ ์ค์ ์ ๋ณด ๊ฐฑ์ ์ด ํ์ํ ๋๋ง๋ค /actuator/refresh ์ ๊ฐ์ ์๋ ํฌ์ธํธ๋ฅผ ํธ์ถํ๋ ๋จ์ ์ด ์๋ค.
๋ง์ดํฌ๋ก ์๋น์ค ํ๊ฒฝ๊ณผ ๊ฐ์ ๋
๋ฆฝ๋ ์๋ง์ ํด๋ผ์ด์ธํธ๊ฐ ์กด์ฌํ๋ค๋ฉด, ์ค์ ์ ๋ณด์ ๊ฐฑ์ ์ ์ํด ๋ชจ๋ ํด๋ผ์ด์ธํธ๋ฅผ ํธ์ถํ๋ ๊ฒ๋ ๋ฒ๊ฑฐ์ธ ๊ฒ์ด๋ค.
๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ Spring Cloud Bus๋ฅผ ์ ์ฉํ๋ฉด ์ค์ ์ ๋ณด๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ฐ๊ฒฐ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ๊ฐ ํ ๋ฒ์ ๊ฐฑ์ ๋๋๋ก ํ ์ ์๋ค.
๋ชจ๋ ์๋ฒ์ ๋ํด refresh๋ฅผ ํธ์ถํ๋ ๊ฒ์ด ์๋ ๋จ ํ ๊ฐ์ ํด๋ผ์ด์ธํธ์๋ง ํธ์ถํ๋ฉด ๋ชจ๋ ํด๋ผ์ด์ธํธ๊ฐ ๊ฐฑ์ ๋๋ค๋ ๊ฒ์ด๋ค.
2021๋ 1์ ๋ด์ฉ ์ถ๊ฐ: ์คํ๋ง ๋ถํธ 2.4 ๋ฒ์ ๋ถํฐ๋ ์ด ๊ธ์ ์์ ์์ ์ฌ์ฉ๋
bootstrap.ymlํ์ผ์ ๋ ์ด์ ์ฌ์ฉํ์ง ์์ต๋๋ค. ๋ํ ๊ธ์ ์์ ์์ ์ฌ์ฉํ โ์ค์ ๊ฐ ๊ฐฑ์ ์ ์ํ actuator ์๋ํฌ์ธํธโbus-refresh๋busrefresh๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ๋ํด์๋ ์๋จ ๋ชฉ์ฐจ์ ๋ค ๋ฒ์งธ ๊ธ โSpring Boot 2.4 ๋ฒ์ ์์์ ๋ณ๊ฒฝ์ฌํญโ์ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
์ด๋ค ๊ตฌ์กฐ์ผ๊น?
๊ฐ๋จํ๊ฒ ๊ตฌ์กฐ๋ฅผ ์ดํด๋ณด์. ์์ ๊ธ์ ๊ตฌ์กฐ์ ๋์ผํ๊ฒ ์ค์ ํ์ผ์ Git ์ ์ฅ์์ ์์นํ๋ค. config ์๋ฒ๋ Git ์ ์ฅ์์์ ์ต์ ์ค์ ์ ๋ณด๋ฅผ ๊ฒ์ํ์ฌ ํด๋ผ์ด์ธํธ๋ฅผ ์ํ ์ค์ ์ง์ค์ ์๋น์ค๋ก์์ ์ญํ ์ ์ํํ๋ฉฐ ํด๋ผ์ด์ธํธ๋ ๊ตฌ๋๋ ๋ config ์๋ฒ๋ก๋ถํฐ ์ค์ ์ ๋ณด๋ฅผ ๋ฐ์์จ๋ค.
๊ทธ๋ฆฌ๊ณ ํด๋ผ์ด์ธํธ๋ Spring Cloud Bus๋ฅผ ํตํด ์๋ก ์ฐ๊ฒฐ๋๋ค. ์คํ๋ง ํด๋ผ์ฐ๋๋ RabbitMQ์ Kafka ๊ฐ์ ๊ฒฝ๋ ๋ฉ์์ง ๋ธ๋ก์ปค๋ฅผ ์ฌ์ฉํ๋๋ฐ
์ด๋ฒ ์์ ์์๋ RabbitMQ๋ฅผ ์ฌ์ฉํ๋ฉฐ ์ฐ๊ฒฐ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ๋ก ์ด๋ฒคํธ๋ฅผ ๋ธ๋ก๋์บ์คํธ(broadcast) ํ๋ค.

ํํธ ์ค์ ํ์ผ์ ๋ณ๊ฒฝํ ํ Git ์ ์ฅ์๋ก push ํ๋ค๋ฉด, ์ค์ ๊ฐ์ ๊ฐฑ์ ํ๊ธฐ ์ํด์ ํด๋ผ์ด์ธํธ์ actuator/bus-refresh ์๋ ํฌ์ธํธ๋ฅผ ํธ์ถํ๋ค.
์ฌ๊ธฐ์ ๊ธฐ์กด ๊ตฌ์ฑ๊ณผ์ ์ฐจ์ด๋ ๋จ ํ๋์ ํด๋ผ์ด์ธํธ๋ง ํธ์ถํด๋ RabbitMQ๋ก ์ฐ๊ฒฐ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ์์ ์ค์ ๊ฐ์ด ๊ฐฑ์ ๋๋ค๋ ๊ฒ์ด๋ค.
config ์๋ฒ๋ Git ์ ์ฅ์์์ ์ต์ ์ค์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ config ์๋ฒ ์์ฒด๋ฅผ ๊ฐฑ์ ํ๋ค. ์ดํ ํด๋ผ์ด์ธํธ๊ฐ ์ค์ ์ ๋ณด๋ฅผ ์์ฒญํ๋ฉด ์ต์ ์ผ๋ก ์ ๋ฐ์ดํธ๋ ์ค์ ์ ๋ณด๊ฐ ์ ๊ณต๋๋ค.
์ด์ ์ง์ ์ฝ๋ ์์ฑํด๋ณด๋ฉฐ Spring Cloud Bus๋ฅผ ํ์ ํด๋ณด์.
์์ ์์ ์ฌ์ฉํ ์ฝ๋๋ ๋ชจ๋ github์ ์์ต๋๋ค. ๊ธ ํ๋จ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.
RabbitMQ ๊ตฌ์ถ๊ณผ ์คํ
RabbitMQ๋ฅผ ๊ตฌ์ถํ๊ณ ์คํํ๋ ๊ณผ์ ์ Docker๋ฅผ ์ด์ฉํ์ฌ ๋ก์ปฌ ํ๊ฒฝ์์ ์งํํ๋ค. ์๋์ ๊ฐ์ด ์คํํ๋ฉด ๋๋๋ฐ ์ต์
์ ์ดํด๋ณด์.
์ฐ์ RabbitMQ ์ฐ๋์ 5672๋ฒ ํฌํธ๋ฅผ ์ฌ์ฉํ๊ณ ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ์ด์ฉํ๋ ์ด๋๋ฏผ ํ์ด์ง๋ 8087๋ฒ ํฌํธ๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋ก๊ทธ์ธ์ ์ฌ์ฉ๋๋ ์์ด๋๋ madplay์ด๊ณ ๋น๋ฐ๋ฒํธ๋ ๋์ผํ๋ค.
$ docker run -d --name rabbitmq \
-p 5672:5672 -p 8087:15672 \
-e RABBITMQ_DEFAULT_USER=madplay \
-e RABBITMQ_DEFAULT_PASS=madplay \
rabbitmq:management
์ ์์ ์ผ๋ก ๊ตฌ๋๋์๋ค๋ฉด ๋ธ๋ผ์ฐ์ ๋ฅผ ์ด๊ณ http://localhost:8087๋ก ์ ์ํด๋ณด์. ์๋์ ๊ฐ์ ํ๋ฉด์ด ๋ณด์ผ ํ
๋ฐ ์ปจํ
์ด๋๋ฅผ ๋์ธ ๋ ์ฌ์ฉํ
๊ณ์ ์ ๋ณด๋ฅผ ์
๋ ฅํด์ ๋ก๊ทธ์ธํ๋ฉด ๋๋ค.

Spring Cloud Config Client ์์
ํด๋ผ์ด์ธํธ์ ์ฝ๋๋ฅผ ์์ ํด์ผ ํ๋ค. ์๋์ ๊ฐ์ด pom.xml์ ์์กด์ฑ์ ์ถ๊ฐํด์ค๋ค. Spring Cloud Bus๋ฅผ ์ํ ์์กด์ฑ์ด๋ค.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
๊ทธ๋ฆฌ๊ณ application.yml ํ์ผ์ ์๋์ ๊ฐ์ด ์์ฑํ๋ค. ๋ฌผ๋ก ์์ ์์ ์ฒ๋ผ bootstrap.yml๋ก ์ฌ์ฉํด๋ ์คํ๋์ง๋ง ๊ธฐ๋ฅ๊ณผ ํ์์ ๋ฐ๋ผ ๊ตฌ๋ถํด๋ณด์.
๋ฐ๋ผ์ ์ด๋ฒ ์์ ์์๋ ์ค์ ๊ฐ์ ๊ฐฑ์ ํ๋ ์๋ ํฌ์ธํธ ์ค์ ์ application.yml ์ ์์ฑํ๋ค.
server:
port: 8089
spring:
rabbitmq: # RabbitMQ ๊ด๋ จ ์ค์
host: localhost
port: 5672
username: madplay
password: madplay
management:
endpoints:
web:
exposure:
include: bus-refresh
๋ค์์ผ๋ก bootstrap.yml ํ์ผ์๋ ์๋์ ๊ฐ์ด ์์ฑํ๋ค.
spring:
profiles: # ์ฌ๊ธฐ์ ์ง์ ํด๋ ๋๊ณ , ์คํํ ๋ ์ง์ ํด๋ ๋๋ค.
active: dev
application:
name: config
cloud:
config:
uri: http://localhost:8088
์์ ์ ๋๋ฌ๋ค. config ์๋ฒ๋ ์์ ํ์ง ์์๋ ๋๋ค.
ํ์ธํด๋ณด๊ธฐ
ํ
์คํธ๋ฅผ ์ํ ์ค๋น๋ ๋ชจ๋ ๋๋ฌ๋ค. RabbitMQ์ Config ์๋ฒ ๊ทธ๋ฆฌ๊ณ Config ํด๋ผ์ด์ธํธ ๋ชจ๋๋ฅผ ์คํํด๋ณด์. bootstrap.yml์ active profiles์
์ง์ ํ๊ธฐ ๋๋ฌธ์ ๋ณ๋ค๋ฅธ ์ต์
์์ด ์คํํด๋ ๋๋ค. ์ง์ ์ง์ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ์๋ -Dspring.profiles.active=dev ์ฒ๋ผ ๊ฐ์ ์ฃผ๋ฉด ๋๋ค.
๋๋ Intellij IDE๋ฅผ ์ฌ์ฉํ๋ค๋ฉด Run/Debug Configuration์ Active Profiles์ ์ง์ ํ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
์ด๋ฒ ํ
์คํธ์์๋ RabbitMQ์ ์ฐ๊ฒฐ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ๊ฐ ๊ฐฑ์ ๋๋์ง ํ์ธํ๊ธฐ ์ํด 2๊ฐ์ ํด๋ผ์ด์ธํธ๋ฅผ ๊ตฌ๋ํ ๊ฒ์ด๋ค.
ํด๋ผ์ด์ธํธ๋ฅผ ๋์ด ํ์ application.yml์ server.port ๋ถ๋ถ์ 8086๋ฒ ํฌํธ๋ก ์์ ํ์ฌ ๋ ๋ค๋ฅธ ํด๋ผ์ด์ธํธ๋ฅผ ๊ตฌ๋์์ผ ๋ณด์.
์ฆ, ์๋์ ๊ฐ์ด ํฌํธ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค.
- 8086๋ฒ ํฌํธ: Config ํด๋ผ์ด์ธํธ 2
- 8087๋ฒ ํฌํธ: RabbitMQ
- 8088๋ฒ ํฌํธ: Config ์๋ฒ
- 8089๋ฒ ํฌํธ: Config ํด๋ผ์ด์ธํธ 1
2๊ฐ์ ํด๋ผ์ด์ธํธ๊ฐ ๋ชจ๋ ์ ์์ ์ผ๋ก ๊ตฌ๋๋๋ฉด RabbitMQ ์ด๋๋ฏผ ํ์ด์ง๋ฅผ ํตํด์ ์ ์ ์ฐ๊ฒฐ๋๋์ง ํ์ธํ ์ ์๋ค.
๋จผ์ Exchanges ํญ์์ springCloudBus๊ฐ ์ถ๊ฐ๋ ๊ฒ๊ณผ Connection ํญ์์ ์ฐ๊ฒฐ ์ํ๋ฅผ ํ์ธํ ์ ์๋ค.

์ค์ ๊ฐ ๋ณ๊ฒฝ์ ํ ์คํธํ๊ธฐ ์ ์ ํด๋ผ์ด์ธํธ๋ฅผ ๊ฐ๊ฐ ํธ์ถํด์ ํ์ฌ์ ๊ฐ์ ํ์ธํด๋ณด์.
$ curl -X GET "http://localhost:8089/dynamic"
# ๊ฒฐ๊ณผ
{
"profile": "I'm dev taeng",
"comment": "Hello! updated dev taeng!!!"
}
$ curl -X GET "http://localhost:8086/dynamic"
# ๊ฒฐ๊ณผ
{
"profile": "I'm dev taeng",
"comment": "Hello! updated dev taeng!!!"
}
๋ ๊ฐ์ ํด๋ผ์ด์ธํธ ๋ชจ๋ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ด๊ณ ์๋ค. ๊ฐ์ ํ์ธํ๋ค๋ฉด Git Repository์ ์๋ config-dev.yml ํ์ผ์ ๋ด์ฉ์ ์์ ํด๋ณด์.
github๋ฅผ ํตํด์ ๋ฐ๋ก ์งํํด๋ ๋๊ณ , ๋ก์ปฌ์์ ํ์ผ์ ์์ ํ ํ์ commit ํ push ํด๋ ๋๋ค.
taeng:
profile: I'm dev taeng
comment: Hello! updated by Spring Bus.
๊ทธ๋ฆฌ๊ณ ํด๋ผ์ด์ธํธ ํ๋์๋ง ์๋์ ๊ฐ์ ์์ฒญ์ ๋ณด๋ด๋ฉด ๋๋ค. ๊ธฐ์กด ๋ฐฉ์์ด๋ผ๋ฉด ๋ชจ๋ ํด๋ผ์ด์ธํธ์ ๊ฐฑ์ ์์ฒญ์ ํด์ผ ํ์ง๋ง
์ด์ ๋ ํ๋์ ํด๋ผ์ด์ธํธ๋ง ํธ์ถํด๋ RabbitMQ๋ก ์ฐ๊ฒฐ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ๊ฐ ๊ฐฑ์ ๋๋ค.
์ฌ๋ฌ ๋๋ก ๊ตฌ์ฑ๋ ํด๋ผ์ด์ธํธ๋ฅผ ํ๋์ฉ ๋ชจ๋ ํธ์ถํ ํ์๊ฐ ์๋ค๋ ๋ป์ด๋ค.
$ curl -X POST "http://localhost:8089/actuator/bus-refresh"
์ด์ ๋ค์ ํด๋ผ์ด์ธํธ๋ฅผ ํธ์ถํด์ ๊ฐ์ด ๋ณ๊ฒฝ๋์๋์ง ํ์ธํด๋ณด์.
$ curl -X GET "http://localhost:8089/dynamic"
# ๊ฒฐ๊ณผ
{
"profile": "I'm dev taeng",
"comment": "Hello! updated by Spring Bus."
}
$ curl -X GET "http://localhost:8086/dynamic"
# ๊ฒฐ๊ณผ
{
"profile": "I'm dev taeng",
"comment": "Hello! updated by Spring Bus."
}
๊ทธ๋ ๋ค! ํ๋์ ํด๋ผ์ด์ธํธ์๋ง ๊ฐฑ์ ์์ฒญ์ ํ์ง๋ง ๋ค๋ฅธ ํด๋ผ์ด์ธํธ๊น์ง ์ฐธ์กฐํ๊ณ ์๋ ์ค์ ๊ฐ์ด ์ต์ ์ผ๋ก ๋ณ๊ฒฝ๋์๋ค.
์ด๋ฒ ๊ธ ๋์
๋ถ์์ ๋ณด์๋ ๊ตฌ์กฐ์ฒ๋ผ Spring Cloud Bus์ ์ฐ๊ฒฐ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ์์ ์ค์ ๊ฐ ๊ฐฑ์ ์ ์ํ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ผ๋ฉฐ
@RefreshScope ์ด๋
ธํ
์ด์
์ด ๋ฌ๋ฆฐ ๋ชจ๋ ๋น(Bean)์ ๊ฐฑ์ ์ด๋ฒคํธ์ ์ํด config ์๋ฒ๋ก๋ถํฐ ์ต์ ์ค์ ๊ฐ์ ๋ฐ๋๋ค.
์ด ๊ณผ์ ์ Spring Cloud Bus๋ฅผ ํตํด ์ค์ ๊ฐ์ด ๊ฐฑ์ ๋ ๋, ์๋ฒ์ ํด๋ผ์ด์ธํธ์ ๋ก๊ทธ๋ฅผ ํตํด์๋ ์ ์ ์๋ค.
# Server ๋ก๊ทธ
Fetched for remote master and found 1 updates
The local repository is dirty or ahead of origin. Resetting it to origin/master.
Reset label master to version AnyObjectId[52c3482316dd84c80f3a29fb7ba899548c7a4b2b]
Adding property source: file:/var/folders/7b/4vlwnfvd5r54h9fdd89qtnqm0000gn/T/config-repo-10779098978969336911/config-dev.yml
Adding property source: file:/var/folders/7b/4vlwnfvd5r54h9fdd89qtnqm0000gn/T/config-repo-10779098978969336911/config-dev.yml
# Client1 ๋ก๊ทธ
Fetching config from server at : http://localhost:8088
Located environment: name=config, profiles=[dev], label=null, version=52c3482316dd84c80f3a29fb7ba899548c7a4b2b, state=null
Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'},
BootstrapPropertySource {name='bootstrapProperties-https://github.com/madplay/spring-cloud-config-repository/config-dev.yml'}]
The following profiles are active: dev
Started application in 1.982 seconds (JVM running for 316.229)
Received remote refresh request. Keys refreshed [config.client.version, taeng.comment]
# Client2 ๋ก๊ทธ
Fetching config from server at : http://localhost:8088
Located environment: name=config, profiles=[dev], label=null, version=52c3482316dd84c80f3a29fb7ba899548c7a4b2b, state=null
Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'},
BootstrapPropertySource {name='bootstrapProperties-https://github.com/madplay/spring-cloud-config-repository/config-dev.yml'}]
The following profiles are active: dev
Started application in 1.06 seconds (JVM running for 794.7)
Received remote refresh request. Keys refreshed [config.client.version, taeng.comment]
๋ง์น๋ฉฐ
์ฒ์ ๊ธ์์๋ Spring Cloud Config๋ฅผ ์ด์ฉํ์ฌ ์ค์ ํ์ผ์ ์ธ๋ถ๋ก ๋ถ๋ฆฌํ์ฌ ๋น๋, ๋ฐฐํฌ ์์ด๋ ๊ฐฑ์ ํ ์ ์๋๋ก ํ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฒ ๊ธ์์๋ Spring Cloud Bus๋ฅผ ํตํด ์ค์ ๊ฐ์ ๊ฐฑ์ ํ๊ธฐ ์ํด ๋ชจ๋ ํด๋ผ์ด์ธํธ๋ฅผ ํธ์ถํ๋ ๋ถํธํจ์ ์์ ๋ณด์๋ค.
๊ทธ๋ฐ๋ฐ ์ค์ ๊ฐ์ด ๊ฐฑ์ ๋ ๋๋ง๋ค ํธ์ถํ๋ ๊ฒ์กฐ์ฐจ ๋ถํธํ๋ค๊ณ ๋๋ ์ ์๋ค. ์ด๋ฌํ ํธ์ถ์กฐ์ฐจ ์์จ ์ ์์ง ์์๊น? ์ด์ด์ง๋ ๊ธ์์ ์ค์ ํ์ผ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์๋์ผ๋ก ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํฌ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณธ๋ค.
์์ ์์ค ์ฝ๋
์ด๋ฒ ๊ธ์์ ์ฌ์ฉํ ์์ค ์ฝ๋๋ ๋ชจ๋ ์๋ ์ ์ฅ์์ ์์ต๋๋ค.
- config server & config client
- config repository