๋งค์ผ๋ฉ์ผ ๋ฐฑ์๋ ์ง๋ฌธ์ ์ฐธ๊ณ ํด ๊ฐ์ธ์ ์ผ๋ก ํ์ตํ ๋ด์ฉ์ ์ ๋ฆฌํ์์ต๋๋ค.
์ค๋ฅ๊ฐ ์๋ค๋ฉด ์ธ์ ๋ ํผ๋๋ฐฑ ์ฃผ์๋ฉด ๋ฐ๋ก ๋ฐ์ํ๊ฒ ์ต๋๋ค..!
ํฌ์ค์ฒดํฌ๋?
ํฌ์ค์ฒดํฌ(Health Check)๋ ํ์ฌ ์๋ฒ๋ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ํ๊ฐ ์ ์์ธ์ง ํ์ ํ๋ ๊ฒ์ ์๋ฏธํจ
=> API ์๋ํฌ์ธํธ๋ฅผ ํธ์ถํ๊ฑฐ๋ ํน์ ํฌํธ๋ก TCP ์ฐ๊ฒฐ์ ์๋ํ๋ ๋ฐฉ์์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, Spring Actuator๋ฅผ ํ์ฉํ์ฌ ํฌ์ค์ฒดํฌ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์
์ด๋ฐ ํฌ์ค์ฒดํฌ๋ ๋ก๋ ๋ฐธ๋ฐ์๋ ์ค์ผ์คํธ๋ ์ด์ ๋๊ตฌ(ECS, Kubernetes ๋ฑ)๊ฐ ์๋ฒ ์ํ๋ฅผ ํ๋จํ๊ณ ํธ๋ํฝ์ ํจ์จ์ ์ผ๋ก ๋ถ์ฐํ๋ ๋ฐ์ ํต์ฌ์ ์ธ ์ญํ ์ํจ
ํฌ์ค์ฒดํฌ๊ฐ ์ ํ์ํ ๊น?
๋ฐฐํฌ ์ํ ํ์ธ
์๋ก์ด ๋ฒ์ ์ ๋ฐฐํฌํ ์งํ, ์ดํ๋ฆฌ์ผ์ด์ ์ด ์ ์์ ์ผ๋ก ๊ธฐ๋๋์๋์ง ์๋์ผ๋ก ํ์ธํ ์ ์์
=> ํฌ์ค์ฒดํฌ๊ฐ ํต๊ณผ๋์ด์ผ๋ง ์ค์ ํธ๋ํฝ์ด ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์, ๋ฌธ์ ๊ฐ ์๋ ์๋ฒ์ ์์ฒญ์ด ๊ฐ์ง ์๋๋ก ๋ฐฉ์งํ ์ ์์
์ฅ์ ์กฐ๊ธฐ ๊ฐ์ง ๋ฐ ๋์
์๊ธฐ์น ์์ ์๋ฌ๋ ์์ ๊ณ ๊ฐ(CPU, ๋ฉ๋ชจ๋ฆฌ ๋ฑ)์ด ๋ฐ์ํ ๊ฒฝ์ฐ, ํฌ์ค์ฒดํฌ ์คํจ๋ฅผ ํตํด ์๋ฒ๊ฐ ๋น์ ์ ์ํ์์ ๋น ๋ฅด๊ฒ ํ์งํ ์ ์์
=> ์ด๋ก ์ธํด ๋ก๋ ๋ฐธ๋ฐ์๊ฐ ํด๋น ์๋ฒ๋ฅผ ํธ๋ํฝ ๋ถ์ฐ ๋์์์ ์ ์ธํ์ฌ ์ฅ์ ํ์ฐ์ ๋ง์ ์ ์์
์๋ํ๋ ๋ฌด์ค๋จ ๋ฐฐํฌ (Docker, ECS, K8s ๋ฑ)
๋ง์ ํด๋ผ์ฐ๋ ํ๊ฒฝ์์ ํฌ์ค์ฒดํฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์๋ ๋กค๋ง ์ ๋ฐ์ดํธ์ ๋ฌด์ค๋จ ๋ฐฐํฌ๋ฅผ ์ ๊ณตํจ
=> ์ ์ธ์คํด์ค Healthy ์ํ๊ฐ ๋๊ธฐ ์ ๊น์ง๋ ํธ๋ํฝ์ ๋๊ธฐ์ง ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๋ ๋ฌธ์ ์์ด ์๋น์ค๋ฅผ ์ด์ฉํ ์ ์์
๋กค๋ง ์ ๋ฐ์ดํธ(Rolling Update)๋ ๋ฐฐํฌ ์ ๋ต ์ค ํ๋๋ก, ์ ์ฒด ์๋น์ค๋ฅผ ํ ๋ฒ์ ์ค๋จํ์ง ์๊ณ ํ๋์ฉ(๋๋ ์์์ฉ) ์์ฐจ์ ์ผ๋ก ์ ๋ฐ์ดํธํ๋ ๋ฐฉ์์
=> ์๋ฒ ์ฌ๋ฌ ๋ ์ค์์ ํ ๋์ฉ ์ ๋ฐ์ดํธ ํ๊ณ , ๋ฌธ์ ๊ฐ ์์ผ๋ฉด ๋ค์ ์๋ฒ๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ์์ผ๋ก ์ ์ฒด ์๋ฒ๋ฅผ ํ ๋ฒ์ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ์๊ณผ๋ ๋ฌ๋ฆฌ, ์ฌ์ฉ์๋ ์๋น์ค ์ค๋จ์ ๊ฑฐ์ ๋๋ผ์ง ๋ชปํ๋ค๋ ์ฅ์ ์ด ์์
ํฌ์ค์ฒดํฌ์ ๋ฐฉ์
HTTP ํฌ์ค์ฒดํฌ
๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ์์ผ๋ก, ์ง์ ๋ ์๋ํฌ์ธํธ์ ์ฃผ๊ธฐ์ ์ผ๋ก HTTP ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต ์ํ ์ฝ๋๋ฅผ ํ์ธํจ
GET /health
200 OK
TCP ํฌ์ค์ฒดํฌ
ํน์ ํฌํธ์ TCP ์ฐ๊ฒฐ์ ์๋ํ์ฌ ์๋ฒ๊ฐ ์์ ๊ฐ๋ฅํ ์ํ์ธ์ง ํ์ธํจ
=> HTTP ์๋ฒ๊ฐ ์์ ํ ๊ธฐ๋๋์ง ์์๋๋ผ๋, ํ๋ก์ธ์ค ๋ ๋ฒจ์์ ๋์ ์ฌ๋ถ๋ฅผ ํ๋จํ ์ ์์
์๋ฅผ ๋ค์ด Spring Boot ์๋ฒ๋ผ๋ฉด, ์ ํ๋ฆฌ์ผ์ด์ ์ด ์คํ๋๋ฉด์ Bean ์ด๊ธฐํ, DB ์ฐ๊ฒฐ, ์ค์ ๋ก๋ฉ ๋ฑ์ด ์์ ํ ๋๋์ง ์์๋๋ผ๋ ์ด๋ฏธ ํฌํธ(ex. 8080)๋ฅผ ์ด๊ณ TCP ์์ ๋๊ธฐ(listen) ํ๊ณ ์์ ์ ์์
์ด ์์ ์์๋ HTTP ์์ฒญ์ ๋ฐ๋๋ผ๋ ์๋ฌ๋ฅผ ๋ฑ์ ์ ์์ง๋ง, TCP ์์ค์์๋ ์ฐ๊ฒฐ์ ๊ฐ๋ฅํจ
=> ์ฆ, telnet <IP> <PORT>๋ ์ฑ๊ณตํจ
(ํ๋ก์ธ์ค๋ ์ด์ ์์)
Spring Boot์์ ํฌ์ค์ฒดํฌ ๊ตฌํํ๊ธฐ
Spring Boot์์๋ Spring Boot Actuator ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ํฌ์ค์ฒดํฌ๋ฅผ ๋งค์ฐ ๊ฐํธํ๊ฒ ๊ตฌํํ ์ ์์
// build.gradle
implementation 'org.springframework.boot:spring-boot-starter-actuator'
# application.yml
management:
endpoints:
web:
exposure:
include: health, info
์ด๋ ๊ฒ ์ค์ ์ ํ๊ฒ๋๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก /actuator/health ์๋ํฌ์ธํธ๊ฐ ์์ฑ๋๋ฉฐ
{
"status": "UP"
}
์์ ๊ฐ์ JSON ์๋ต์ ์ ๊ณตํจ
(์ถ๊ฐ๋ก, DB, Redis, Kafka, S3 ๋ฑ์ ์์กด์ฑ๊น์ง ํฌํจํ ๋ณตํฉ ํฌ์ค์ฒดํฌ๋ ๊ฐ๋ฅํจ)
ํฌ์ค์ฒดํฌ ์คํจ ์์ ์๋๋ฆฌ์ค ์์
์๋ฒ A, B ๋ ๋๊ฐ ์๊ณ ๋ก๋ ๋ฐธ๋ฐ์๊ฐ ์์ฒญ์ ๊ท ๋ฑํ๊ฒ ๋ถ์ฐํ๊ณ ์๋ ํ๊ฒฝ์ด ์๋๋ฐ
(์ ๊ธฐ์ ์ผ๋ก /health ์๋ํฌ์ธํธ๋ฅผ ์ด์ฉํ ํฌ์ค์ฒดํฌ ์ํ์ค)
์๋ฒ A์์ DB ์ฐ๊ฒฐ ์คํจ ๋๋ ๋ฉ๋ชจ๋ฆฌ ๋์๋ก ์ธํ GC ๋ณ๋ชฉ์ด ๋ฐ์ํด์ /health ์๋ต์ด ์คํจ๊ฐ๋ ์ํฉ์
๊ทธ๋ผ ๋ก๋ ๋ฐธ๋ฐ์๋ ์๋ฒ A๋ฅผ ํธ๋ํฝ ๋์์์ ์ ์ธํ๊ณ ๋ชจ๋ ์์ฒญ์ ์ ์ ์๋ฒ์ธ B๋ก ์ ๋ฌ๋จ
=> ๊ด๋ฆฌ์ ๋๋ ๋ชจ๋ํฐ๋ง ์์คํ ์ด A์ ์ํ๋ฅผ ๊ฐ์งํ๊ณ ์๋ ์ฌ์์ ๋๋ ์๋ฆผ์ ๋ฐ์กํ๊ฒ๋จ
์ด๋ ๊ฒ ๋๋ฉด
- ์ฌ์ฉ์์๊ฒ ์ฅ์ ์๋ฒ์ ์ค๋ฅ ์๋ต์ด ์ ๋ฌ X
- ์๋ ๋ณต๊ตฌ ๋๋ ์๋ ์ ๊ฒ๊น์ง ์์ ํ ์ํ ์ ์ง ๊ฐ๋ฅ
- ํด๋ผ์ด์ธํธ์ ์ฌ์๋๋ก ์ธํด ์ ์ฒด ํธ๋ํฝ์ด ์ฆ๊ฐํ๋ ๋๋ฏธ๋ ธ ํ์(์ฅ์ ) ๋ฐฉ์ง
์ ๊ฐ์ ์ฅ์ ์ด ์์
ํฌ์ค์ฒดํฌ ์ค๊ณ ์ ์ฃผ์์ฌํญ
1. ๋๋ฌด ๋ฌด๊ฑฐ์ด ์ฐ์ฐ ๊ธ์ง
ํฌ์ค์ฒดํฌ๋ ์์ฃผ ํธ์ถ๋๋ฏ๋ก, DB ์ฟผ๋ฆฌ ๋ฑ์ ๊ฐ๋จํ๊ณ ๋น ๋ฅด๊ฒ ์ํ๋๋ ๊ฒ์ผ๋ก ๊ตฌ์ฑํด์ผํจ
2. /healthz vs /readyz
Kubernetes์์๋ liveness(์ด์์๋์ง)์ readiness(์์ฒญ์ ๋ฐ์ ์ค๋น๊ฐ ๋์๋์ง)๋ฅผ ๋ถ๋ฆฌํด์ ์ฒดํฌํจ
Spring Actuator์์ ๊ธฐ๋ณธ /health๋ ๋ชจ๋ ์ํ(DB, Redis ๋ฑ ํฌํจ)๋ฅผ ๋ค ํ์ธํจ
๊ทธ๋ฐ๋ฐ ์๋น์ค๊ฐ ์ฒ์ ์์๋ ๋, DB ์ฐ๊ฒฐ์ด ์์ง ์๋์ด ์์ด์ /health์์ ์คํจํ ์ ์๊ธฐ์ liveness์ readiness๋ฅผ ๊ตฌ๋ถํจ
๊ตฌ๋ถ | ์๋ฏธ | ์คํจ ์ ํ๋ | ์์ |
liveness | ์ฑ์ด ์ด์์๋๊ฐ? (์ฃฝ์๋์ง ํ์ธ) | ์ฌ์์ํจ | OutOfMemory ๋ฑ |
readiness | ์์ฒญ ๋ฐ์ ์ค๋น๊ฐ ๋๋๊ฐ? | ํธ๋ํฝ ์ ์ธ๋ง | DB ์ฐ๊ฒฐ ์ ๋จ ๋ฑ |
์ฑ์ ์ด์์์ง๋ง ์์ง ์ค๋น๊ฐ ์ ๋ ์ํฉ(DB ์ฐ๊ฒฐ ์ง์ฐ ๋ฑ)์์๋ readiness๋ง ์คํจํ๋๊ฒ ๋ง๊ณ ๋ง์ฝ ์ด๊ฑธ liveness์์ ์คํจํ๊ฒ ํ๋ฉด, ECS๋ K8s๊ฐ ์ฑ์ ์ฌ์์ํด๋ฒ๋ฆฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ์ปค์ง ์ ์์
=> ๊ทธ๋์ DB ๋ฑ์ readiness์๋ง ํฌํจํ๊ณ , liveness์์๋ ๋จ์ํ ์ ํ๋ฆฌ์ผ์ด์ ๋ง ์ด์์๋์ง๋ง ํ์ธํ๊ฒ ์ค๊ณํ๋ ๊ฒ ์ข์
management:
endpoint:
health:
group:
liveness:
include: ping
readiness:
include: db, redis
/*
/actuator/health/liveness → ๋จ์ “ping”๋ง ํ์ธ (ํญ์ UP)
/actuator/health/readiness → DB, Redis ํฌํจ
*/
์์ ๊ฐ์ด ์ค์ ํ Kubernetes/ECS์์ ์ฌ์ฉํ๋ liveness, readiness probe์ ๊ฐ๊ฐ ๋งคํ ๊ฐ๋ฅํ๊ธฐ๋ ํ๊ณ
@Component("myApi")
public class MyApiHealthIndicator implements HealthIndicator {
@Override
public Health health() {
boolean isApiHealthy = checkMyInternalApi(); // ๋ด๊ฐ ์ ์ํ ์ฒดํฌ ๋ก์ง
return isApiHealthy ?
Health.up().build() :
Health.down().withDetail("error", "API connection failed").build();
}
}
management:
endpoint:
health:
group:
readiness:
include: db, redis, myApi
# myApi๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ฑ๋ก๋ ์ปค์คํ
health indicator๋
# ๊ธฐ๋ณธ /actuator/health์ ํฌํจ๋๊ณ ,
# ๋ช
์์ ์ผ๋ก readiness์ ํฌํจ์ํค๋ ค๋ฉด config์ include: myApi ์ถ๊ฐ
Spring Boot์์ ์ปค์คํ HealthIndicator๋ฅผ ์ ์ํ์ฌ ์ด๋ฅผ ๋ถ๋ฆฌ ๊ตฌํํ ์ ์์
3. ์์กด์ฑ ์ธ๋ถ ์์คํ ํฌํจ ์ฌ๋ถ ๊ฒฐ์
DB, Kafka, Redis ๋ฑ๊ณผ ์ฐ๊ฒฐ ์ํ๋ฅผ ์ฒดํฌํ ์ง ์ฌ๋ถ๋ ์๋น์ค ํน์ฑ์ ๋ฐ๋ผ ํ๋จํจ
=> ์ด๊ธฐ ๊ตฌ๋ ์์ ์๋ DB ์ฐ๊ฒฐ์ด ์ง์ฐ๋ ์ ์์ผ๋ฏ๋ก, readiness์๋ง ํฌํจํ๋ ๋ฐฉ์๋ ๊ณ ๋ คํด์ผํจ
- readiness์ ํฌํจํด์ผ ํ ๋
- DB, Redis, Kafka๊ฐ ์์ผ๋ฉด ์๋น์ค ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐ
=> ์ด ๊ฒฝ์ฐ readiness ์คํจ ์ ํธ๋ํฝ์ ๋ฐ์ง ์๊ฒ ํ๋ ๊ฒ ๋ง์
- DB, Redis, Kafka๊ฐ ์์ผ๋ฉด ์๋น์ค ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐ
- readiness์๋ ์ ์ธํด์ผ ํ ๋
- ์ผ๋ถ ๋น์ฆ๋์ค๋ง ํด๋น ์์คํ
์ ํ์๋ก ํ๊ณ , ์ฑ์ ๋๋ถ๋ถ์ ๋์ ๊ฐ๋ฅํ ๋
(๋๋ ์ด๊ธฐ ๊ตฌ๋ ์ DB๊ฐ ๋ฆ๊ฒ ์ค๋น๋๋๋ฐ๋ ํธ๋ํฝ์ ๋ฐ์๋ ๋๋ ๊ฒฝ์ฐ)
- ์ผ๋ถ ๋น์ฆ๋์ค๋ง ํด๋น ์์คํ
์ ํ์๋ก ํ๊ณ , ์ฑ์ ๋๋ถ๋ถ์ ๋์ ๊ฐ๋ฅํ ๋
'๐ซ Backend > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ECS Fargate๋ก Spring Boot + ALB ๋ฐฐํฌํ๊ธฐ (0) | 2025.07.01 |
---|---|
Spring์์ ๊ฐ์ฒด๋ฅผ Bean์ผ๋ก ๊ด๋ฆฌํ๋ ์ด์ (0) | 2025.06.23 |
application.yml์ ์ด๋ป๊ฒ ๊ด๋ฆฌํด์ผํ ๊น? (1) | 2025.06.21 |
Spring Security์์ ๋ชจ๋ ์๋ฌ๊ฐ 403์ผ๋ก ๋ฐ์ํ๋ ๋ฌธ์ (0) | 2025.05.11 |
[Spring Boot] HTTPS(NginX) ๋ฐฐํฌ ํ๊ฒฝ์์ Swagger ์๋ฌ (0) | 2025.04.18 |