ํด๋น ๊ธ์ Spring Cloud Config์ name, profiles ๊ทธ๋ฆฌ๊ณ Github ๋ฅผ ์ฐ๋ํด์ ์ค์ ํ์ผ ๊ด๋ฆฌํ๊ธฐ์ ์์กดํ๋ ๊ธ์ ๋๋ค. ์ค์ต ํ๊ฒฝ์ ๋ฐ๋ผํ์๋ ค๋ฉด ์ด์ ๊ธ์ ๋์จ ์ค์ต์ ๋ฐ๋ผํ์๊ธธ ๊ถ๊ณ ๋๋ฆฝ๋๋ค.
๋ชฉ์ฐจ
- ์ค์ ์ ๋ณด๋ฅผ ๋ฐ์ํ๋ ์ด์
- Spring Boot Actuator๋?
- Spring Boot Actuator ์ ๊ธฐ๋ฅ๊ณผ Endpoints
- Config Refresh
- Spring Boot Actuator ๋ฅผ ์ด์ฉํด์ ๋ณ๊ฒฝ ์ ๋ณด ๊ฐฑ์ ํ๊ธฐ
- User-Service์ Actuator ์์กด์ฑ ์ถ๊ฐํ๊ธฐ
- refresh Endpoints ํ์ฑํ
- ์๊ฒฉ ์ ์ฅ์์ ์๋ yml ์ค์ ์ ๋ณด ๋ณ๊ฒฝํ๊ธฐ
- refresh ํ๊ธฐ
์ค์ ์ ๋ณด๋ฅผ ๋ฐ์ํ๋ ์ด์
์ง๊ธ๊น์ง Spring Cloud Config ์ ๋ง์ ๊ธฐ๋ฅ๋ค์ ์์๋ณด์๊ณ ์ค์ตํ๋ค.
ํ์ฌ ์ค์ต ๋ด์ฉ ์ค์์ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ด ๋น ์ก๋ค.
๋ฐ๋ก ์ค์ ์ ๋ณด ๊ฐฑ์ ์ด๋ค.
Spring Boot Application ์ด ์ต์ด์ ๋น๋๋ ๋ bootstrap.yml ๊ณผ application.yml ํ์ผ์ ์๋ ์ ๋ณด๋ฅผ ์ด์ฉํด์ Application์ ๊ตฌ๋์ํจ๋ค.
ํ์ง๋ง ์ง๊ธ ์ํฉ์ ๋ด๋ณด์.
์ต์ด์ Application ์ด ๋น๋๋ ์์ ์๋ง Config ์๋ฒ๋ก๋ถํฐ ์ค์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ณ ํด๋น ์ ๋ณด๋ฅผ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ๋ง์ดํฌ๋ก์๋น์ค๋ค์ด ๋ค์ ๋น๋๋์ง ์๋ ์ด์ ์ค์ ์ ๋ณด๋ ๋ฐ์๋์ง ์๋๋ค.
๊ทธ๋ผ ์ด ์ํฉ์์ ์ด๋ป๊ฒ ํด์ผํ ๊น?
๋ต์ ๊ฐ๋จํ๋ค.
Spring Boot Application ์ ๋ค์ ๊ป๋ค๊ฐ ํค๋ฉด ๋๋ค.
ํ์ง๋ง ๋ ๋ฌธ์ ๊ฐ ์๋ค.
์ฐ๋ฆฌ์ ๋ง์ดํฌ๋ก์๋น์ค๋ค์ ๋จ์ํ๊ฒ ๋์๊ฐ์ง ์๋๋ค. ์ค์ ๋ก๋ CI CD ํ์ดํ๋ผ์ธ๊ณผ ๋๋ถ์ด ๋ค์ํ ์๋ํ์ ์ฎ์ฌ์์ ํ ๋ฐ ์๋์ผ๋ก ์ฑ์ ๊ป๋ค๊ฐ ์ผฐ๋ค๊ฐ ํ๋๊ฒ ๊ณผ์ฐ ์ณ์ ๋ฐฉ๋ฒ์ผ๊น? ๋ง์ฝ ์๋น์ค๊ฐ 100 ๊ฐ๋ผ๋ฉด ๋ค ๊ป๋ค ์ผฐ๋ค๋ฅผ ํด์ผํ ๊น?
์ด ๋ ๋ฑ์ฅํ๋ ๊ฒ์ด ๋ฐ๋ก Spring Boot Actuator ์ด๋ค.
Spring Boot Actuator
Spring Boot includes a number of additional features to help you monitor and manage your application when you push it to production. You can choose to manage and monitor your application by using HTTP endpoints or with JMX. Auditing, health, and metrics gathering can also be automatically applied to your application.
Spring Boot Actuator ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ Production ์ผ๋ก ๋น๋ํ ๋ ์ด๋ฅผ ๋ชจ๋ํฐ๋ง ํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐ ๋์์ด ๋๋ ๊ธฐ๋ฅ์ ๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
HTTP End Point ๋ฅผ ํตํด์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ํ ๊ด๋ฆฌ ๋ฐ ๋ชจ๋ํฐ๋ง์ ํ ์ ์๋๋ก ํ๋ค.
์ฌ์ค์ Actuator ๋ฅผ ์ด์ฉํ๋ค๊ณ ํด์ ์ค์ ์ ๋ณด๋ฅผ ๋ฐ์ํ๊ธฐ ์ํด์ ๊ป๋ค ํค๋ ๊ณผ์ ์ ์๋ตํ ์ ์๋ ๊ฒ์ ์๋๋ค. ๋จ์ง ์กฐ๊ธ ๋ gracefully ํ๊ฒ ์ด ๊ณผ์ ์ ๋ฐ๊พธ๋ ๊ฒ์ด๋ค. ํ ๋ฒ ๊ป๋ค ํค๋๋ฐ, ์ผ๋ง๋ ์ด ๊ณผ์ ์ด ์ฐ์ํด์ง๋์ง ์๋์์ ์ค์ตํด๋ณด๋๋ก ํ์
Spring Boot Actuator ์ ๋ค์ํ ๊ธฐ๋ฅ๊ณผ Endpoints
Spring Boot Actuator ๋ ํจ๊ณผ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ชจ๋ํฐ๋ง๊ณผ ๊ด๋ฆฌ๋ฅผ ์ํด์ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
์ด๋ฅผํ ๋ฉด ํด๋น application์ bean ๋ค์ด ์ด๋ป๊ฒ ์ฌ์ฉ๋๊ณ ๊ด๋ฆฌ๋๋๊ฐ ํน์ ํ์ฌ application์ ์ํ(health)๋ ์ด๋ ํ๊ฐ ๊ทธ๋ฆฌ๊ณ application์ shutdown ํน์ ์ฌ๊ธฐ๋ํ๋ ๋ฐฉ๋ฒ๋ค ๊น์ง ์์ฃผ ๋ค์ํ๋ค.
๋ํ์ ์ธ Endpoints ๋ค์ ๋ด๋ณด์.
- shutdown
- Lets the application be gracefully shutdown. Disabled by default.
- metrics
- Shows ‘metrics’ information for the current application.
- beans
- Displays a complete list of all the Spring beans in your application.
- health
- Shows application health information
- httptrace
- Displays HTTP trace information (by default, the last 100 HTTP request-response exchanges). Requires an HttpTraceRepository bean.
๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ด ์กด์ฌํ๋๋ฐ, ์์ธํ ์ฌํญ์ Spring Boot Actuator ๊ณต์ ๋ฌธ์ ์์ ํ์ธํ ์ ์๋ค.
์ด๋ฐ ๋ค์ํ Endpoint ๋ฅผ ์ด์ฉํ๊ธฐ ์ํด์๋ application.yml ์์ management
์ค์ ๊ฐ์ ์กฐ์ํด์ฃผ๋ฉด ๋๋ค.
์๋ฅผ ๋ค์ด์ health ๊ธฐ๋ฅ๊ณผ beans ๊ธฐ๋ฅ์ ์ด์ฉํ๋ ค ํ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
์ฐ์ actuator ์ ์์กด์ฑ์ ์ถ๊ฐํด์ค์ผ ํ๋ค.
implementation 'org.springframework.boot:spring-boot-starter-actuator'
๊ทธ๋ผ ๋ค์๊ณผ ๊ฐ์ด application.yml ์์ endpoint ๋ฅผ include ํด์ฃผ์.
management:
endpoints:
web:
exposure:
include: health, beans
๊ธฐ๋ณธ ์ค์ ๊ฐ์ผ๋ก health์ info ๊ฐ ์ง์ ๋์ด์๋๋ฐ, ์ฐ๋ฆฌ๋ info ๊ธฐ๋ฅ์ด ์๋ beans ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ค ํ๋ ์์ ๊ฐ์ด ์ง์ ์ง์ ํด์ฃผ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ Spring Boot Application์ด ๋์ํ๋ ์๋ฒ๋ฅผ ํฅํด์ http://server.com/actuator/health
์ GET ์์ฒญ์ ๋ณด๋ด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์ฌ ์ํ์ ์ ๋ณด๊ฐ ๋์ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
Config Refresh
Actuator์ Config Refresh๋ ์๋น์ค์ ๋ฐฐํฌ ๋ฐ ๋น๋ ์์ด ํ๊ฒฝ์ค์ ๋ณ๊ฒฝ ๊ฐ์ ์ ๋ฐ์ดํธ ํ ์ ์๋ค.
์ฐ๋ฆฌ๋ ํด๋น ๊ธฐ๋ฅ์ ์ด์ฉํด์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์ ๊ฐ๋ค์ ๋น๋์ ๋ฐฐํฌ ์์ด ๋ค์ ๋ฐ์์ค๋ ค ํ๋ค.
ํด๋น Endpoint ๋ฅผ ํ์ฑํ์ํค๊ธฐ ์ํด์ ์ญ์ application.yml ํ์ผ์ ์ค์ ์ ๋ณ๊ฒฝํด์ค์ผ ํ๋ค.
management:
endpoints:
web:
exposure:
include: refresh
๊ทธ๋ฆฌ๊ณ ์ด๋ฒ์๋ GET ์์ฒญ์ด ์๋ POST ์์ฒญ์ ๋ณด๋ด์ผ ํ๋ค.
๋ง์ฝ ์ค์ ์ ๋ณด๊ฐ ๋ณ๊ฒฝ๋ ์ด๋ ฅ์ด ์๋ค๋ฉด ์๋ต์ผ๋ก ์ด๋ค ๊ฐ์ด ๋ณ๊ฒฝ๋์๋์ง๋ฅผ ๋ฐ์ ์ ์๋ค.
์์ธํ ๋ด์ฉ์ ์๋์์ ์ง์ ์ค์ต์ ํตํด์ ์์๋ณด์.
Spring Boot Actuator ๋ฅผ ์ด์ฉํด์ ๋ณ๊ฒฝ ์ ๋ณด ๊ฐฑ์ ํ๊ธฐ
์ด์ ์ค์ ๋ก ์ฐ๋ฆฌ์ ๋ง์ดํฌ๋ก์๋น์ค ์ธ์คํด์ค์ธ User-Service ์ ์ด ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉ์์ผ๋ณด๋ ค ํ๋ค.
์ฐ์ ํด๋น ์ค์ต์ ์ํด์๋ Spring Config ์๋ฒ์ User-service๊ฐ ๊ธฐ๋๋์ด ์์ด์ผ ํ๋๋ฐ, ๋ง์ฝ Config ์๋ฒ์ ๋ง์ดํฌ๋ก์๋น์ค๊ฐ ์ค์ ๋ณ๊ฒฝ์ ํ์ธํ ์ ์๋๋ก ํ๊ฒฝ์ด ๊ตฌ์ถ์ด ๋์ด์์ง ์๋ค๋ฉด Spring Cloud Config์ name, profiles ๊ทธ๋ฆฌ๊ณ Github ๋ฅผ ์ฐ๋ํด์ ์ค์ ํ์ผ ๊ด๋ฆฌํ๊ธฐ ์์ ํ์ธํ ์ ์๋ค.
์ฐ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ ๊ณผ์ ์ผ๋ก ์ค์ต์ ์งํํ๋ ค ํ๋ค.
์ค์ต ๊ณผ์
- User-Service์ Actuator ์์กด์ฑ ์ถ๊ฐํ๊ธฐ
- refresh Endpoints ํ์ฑํ
- ์๊ฒฉ ์ ์ฅ์์ ์๋ yml ์ค์ ์ ๋ณด ๋ณ๊ฒฝํ๊ธฐ
- refresh ํ๊ธฐ
User-Service์ Actuator ์์กด์ฑ ์ถ๊ฐํ๊ธฐ
์ฐ๋ฆฌ๊ฐ ์ง๋ ์๊ฐ ๊ตฌ์ฑํ User-Service ์์ Actuator๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ์์กด์ฑ์ ์ถ๊ฐํด๋ณด์.
๋ํ bootstrap ์ ์ด์ฉํด์ ์ค์ ์ ๋ณด๋ฅผ ๋ก๋ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ bootstrap ์์กด์ฑ๋ ํจ๊ป ํ์ํ๋ค.
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
๊ทธ๋ฆฌ๊ณ ๋ณ๊ฒฝ๋ ์ฌํญ์ ํ์ธํ๊ธฐ ์ํด์ User-Service ์ ์ฝ๋๋ฅผ ์กฐ๊ธ ์์ ํ ๊ฒ์ด๋ค.
@SpringBootApplication
@RestController
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
@GetMapping("/config/database")
public String database(@Value("${spring.datasource.driver}") String driver,
@Value("${spring.datasource.url}") String url,
@Value("${spring.datasource.username}") String username,
@Value("${spring.datasource.password}") String password,
@Value("${jwt.token.key}") String tokenKey) {
return "driver: " + driver + "\n"
+ "url: " + url + "\n"
+ "username: " + username + "\n"
+ "password: " + password + "\n\n"
+ "token key: " + tokenKey;
}
}
๊ทธ๋ฆฌ๊ณ ์ง๋ ์๊ฐ ๊ตฌ์ฑํ๋ Git ์ ์ฅ์์ ์๋ config ํ์ผ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ๋์ด์๋ค.
# application.yml
default:
owner: config-service's git folder
content: :) ์๋
ํ์ธ์ ๊ฐ๊ฐ์ ๋ง์ดํฌ๋ก์๋น์ค์์ ์ฌ์ฉ๋ ๋ฐ์ดํฐ์
๋๋ค. :) 2
# user-service.yml
jwt:
token:
key: "{cipher}8fe09399c96cdc1bee0cc3dafea404335a5bdd879e4cd85547fd1e7fbe774e11b3adc2c20634d16501be77987bbc210f"
# user-service-test.yml
spring:
datasource:
driver: com.mysql.jdbc.Driver
url: http://db.com
username: test23
password: test2
refresh Endpoints ํ์ฑํ
์ด์ actuator ์ endpoints ๋ฅผ ์ด๋ฌ์ฃผ๋๋ก ํ์.
์ง๋ ์๊ฐ ํ๊ฒฝ ์ค์ ์ ๋ฐ๋ผ์๋ค๋ฉด ๋ฌธ์ ๊ฐ ์๊ฒ ์ง๋ง ๋ค์ ํ ๋ฒ ์ธ๋ถ ์ค์ ๊ด๋ฆฌ๋ฅผ ์ํ Config ์๋ฒ์ ์ฃผ์๋ ์ ์ด๋ณด์.
spring:
cloud:
config:
uri: http://localhost:8888
name: user-service
profile: test
management:
endpoints:
web:
exposure:
include: refresh
์์ ๋ด์ฉ์ bootstrap.yml ์ ์ ์ด์ฃผ๋๋ก ํ์.
๊ทธ๋ฆฌ๊ณ User ์๋น์ค๋ฅผ ์คํ์์ผ๋ณด์.
ํด๋น ์๋น์ค๋ ๊ณ์ํด์ ์ผ๋์. ์ฐ๋ฆฌ๋ ์ค์ ์ ๋ณด๋ฅผ ๋น๋๋ ์ฌ๊ธฐ๋ ์์ด ๋ฐ์ํ๋ ๊ฒ์ด ๋ชฉ์ ์ด๊ธฐ ๋๋ฌธ์!
์๊ฒฉ ์ ์ฅ์์ ์๋ yml ์ค์ ์ ๋ณด ๋ณ๊ฒฝํ๊ธฐ
ํ์ฌ Config ์๋ฒ์ ๋ง์ดํฌ๋ก์๋น์ค๋ค์ ์๋์ ๊ฐ์ ๊ตฌ์กฐ๋ก ๋์ด์๋ค.
์ด์ Config ์๋ฒ๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ git ์ ์ฅ์์ ์๋ yml ํ์ผ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ์์ ํด๋ณผ ๊ฒ์ด๋ค.
# application.yml
default:
owner: config-service's git folder
content: :) ์๋
ํ์ธ์ ๊ฐ๊ฐ์ ๋ง์ดํฌ๋ก์๋น์ค์์ ์ฌ์ฉ๋ ๋ฐ์ดํฐ์
๋๋ค. :) 2
# user-service.yml
jwt:
token:
key: "{cipher}8fe09399c96cdc1bee0cc3dafea404335a5bdd879e4cd85547fd1e7fbe774e11b3adc2c20634d16501be77987bbc210f"
# user-service-test.yml
spring:
datasource:
driver: com.h2.Driver
url: http://new-db-url.com
username: admin
password: admin
์์ ๊ฐ์ด ์์ ์ ํ๊ณ ์๊ฒฉ ์ ์ฅ์์ push ๋ฅผ ๋ณด๋ด์.
refresh ํ๊ธฐ
์์์ ์ฐ๋ฆฌ๋ config ํ์ผ์ ์์ ํ๊ธฐ ๋๋ฌธ์ ์ค์ ์ค์ ์ ๋ณด๋ ๋ณ๊ฒฝ์ด ๋์๋ค.
ํ์ง๋ง ์ฐ๋ฆฌ์ ์๋ฒ์๋ ๋ณ๊ฒฝ ์ฌํญ์ด ์ ์ฅ๋์ง ์์๋ค.
์ด ๋, Configuration ์ ๋ณด๋ง refresh ํ๋ Actuator์ Refresh ํธ์ถ์ POST๋ก ๋ณด๋ด๋ณด์.
๊ทธ๋ผ ์ด๋ค ์ ๋ณด๊ฐ ๋ณ๊ฒฝ๋์๋์ง ์๋ต์ผ๋ก ์์ ๊ฐ์ด ๋ฐ๊ฒ ๋๊ณ ์๋ฒ์๋ ์๋์ ๊ฐ์ด ์๋ก์ด ์ ๋ณด๊ฐ ๋ฐ์๋๋ ๊ฒ์ ์ ์ ์๋ค.
๋๊ธ