프로덕션 서버가 살아있는지 어떻게 알 수 있는가 — Actuator와 모니터링
프로덕션 서버가 응답하지 않는다. 메모리가 부족한가? DB 연결이 끊겼는가? 스레드가 고갈됐는가? 로그를 봐도 원인이 안 보인다. Spring Boot Actuator가 켜져 있었다면 — GET /actuator/health로 헬스 상태를, GET /actuator/metrics로 메모리/스레드/DB 풀 상태를 즉시 확인할 수 있었다.
이 글은 Actuator의 엔드포인트, 헬스 체크, 메트릭, 그리고 Prometheus + Grafana 통합을 풀어간다. (Spring Boot Reference - Actuator)
Actuator란 — 운영 도구 모음
spring-boot-starter-actuator를 추가하면 프로덕션 준비 기능(헬스 체크, 메트릭, 환경 정보, 스레드 덤프 등)이 자동으로 활성화된다.
# Spring Boot 4 / Java 25 — application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus # 노출할 엔드포인트
endpoint:
health:
show-details: always # 헬스 상세 정보 표시
| 엔드포인트 | URL | 용도 |
|---|---|---|
health |
/actuator/health |
헬스 상태 (UP/DOWN) |
info |
/actuator/info |
애플리케이션 정보 (버전 등) |
metrics |
/actuator/metrics |
JVM/애플리케이션 메트릭 |
prometheus |
/actuator/prometheus |
Prometheus 형식 메트릭 |
env |
/actuator/env |
환경 변수/프로퍼티 |
loggers |
/actuator/loggers |
로그 레벨 조회/변경 |
threaddump |
/actuator/threaddump |
스레드 덤프 |
heapdump |
/actuator/heapdump |
힙 덤프 (다운로드) |
보안: Actuator 엔드포인트는 민감 정보를 노출할 수 있다. 프로덕션에서는
management.endpoints.web.exposure.include로 노출 범위를 최소화하고, Spring Security로 보호한다.
비유: Actuator는 자동차의 계기판이다. 속도계, 온도계, 연료 게이지, 엔진 경고등 — 운전자가 직접 엔진을 열어보지 않아도 핵심 상태를 한눈에 볼 수 있다. /actuator/health는 "엔진 정상?"을, /actuator/metrics는 "현재 연료 양은?"을, /actuator/threaddump는 "엔진 내부 상태 점검"을 제공한다.
내부 메커니즘: Actuator는 어떻게 DB 연결 상태를 아는가? DataSourceHealthIndicator가 주기적으로 SELECT 1 쿼리를 실행해 본다. 쿼리가 성공하면 "UP", 실패하면 "DOWN". 디스크 공간은 DiskSpaceHealthIndicator가 File.getUsableSpace()로 확인한다. 모든 HealthIndicator가 모여 HealthContributor 체인을 구성하고, 하나라도 DOWN이면 전체 상태가 DOWN이 된다. Kubernetes가 /actuator/health를 주기적으로 호출하여 파드의 헬스를 판단한다.
헬스 체크 — health 엔드포인트
# Spring Boot 4 — 헬스 체크
curl http://localhost:8080/actuator/health
{
"status": "UP",
"components": {
"db": {
"status": "UP",
"details": { "database": "PostgreSQL", "validationQuery": "SELECT 1" }
},
"diskSpace": {
"status": "UP",
"details": { "total": 50000000000, "free": 20000000000 }
},
"ping": { "status": "UP" }
}
}
헬스 체크는 DB 연결, 디스크 공간, Redis 연결 등을 자동 검사한다. 컴포넌트 중 하나라도 DOWN이면 전체 상태가 DOWN이 된다. Kubernetes Liveness/Readiness Probe와 결합하여 자동 복구할 수 있다. (Spring Boot - Health
커스텀 헬스 인디케이터
// Spring Boot 4 / Java 25 — 커스텀 헬스 체크
import org.springframework.boot.actuate.health.*;
@Component
public class ExternalApiHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
// 외부 API 연결 확인
checkExternalApi();
return Health.up().withDetail("externalApi", "접근 가능").build();
} catch (Exception e) {
return Health.down().withDetail("error", e.getMessage()).build();
}
}
}
메트릭 — metrics 엔드포인트
# 사용 가능한 메트릭 목록
curl http://localhost:8080/actuator/metrics
{
"names": [
"jvm.memory.used", "jvm.threads.live", "process.cpu.usage",
"http.server.requests", "hikaricp.connections.active",
"hikaricp.connections.pending"
]
}
# 특정 메트릭 상세 조회
curl http://localhost:8080/actuator/metrics/jvm.memory.used
{
"name": "jvm.memory.used",
"measurements": [{ "statistic": "VALUE", "value": 123456789 }],
"availableTags": [{ "tag": "area", "values": ["heap", "nonheap"] }]
}
핵심 메트릭
| 메트릭 | 의미 | 주의 임계값 |
|---|---|---|
jvm.memory.used |
JVM 힙 사용량 | 힙의 80% 초과 시 경고 |
hikaricp.connections.active |
DB 연결 풀 활성 연결 | 풀 크기의 80% 초과 시 경고 |
hikaricp.connections.pending |
대기 중인 연결 요청 | 0 초과 시 풀 확장 검토 |
http.server.requests |
HTTP 요청 지연/카운트 | p99 > 1초 시 경고 |
process.cpu.usage |
프로세스 CPU 사용률 | 80% 초과 시 경고 |
jvm.threads.live |
활성 스레드 수 | 급증 시 스레드 누수 의심 |
Prometheus + Grafana 통합
# application.yml — Prometheus 메트릭 활성화
management:
endpoints:
web:
exposure:
include: health,prometheus
metrics:
tags:
application: my-service # 모든 메트릭에 애플리케이션 태그 추가
# Prometheus 설정 (prometheus.yml)
scrape_configs:
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app:8080']
Prometheus가 주기적으로
/actuator/prometheus를 스크랩하여 메트릭을 수집한다. Grafana에서 Prometheus를 데이터 소스로 연결하여 대시보드를 만든다. (Spring Boot - Prometheus
커스텀 메트릭 — MeterRegistry
// Spring Boot 4 / Java 25 — 커스텀 메트릭
import io.micrometer.core.instrument.*;
@Service
public class OrderService {
private final Counter orderCounter;
private final Timer orderTimer;
public OrderService(MeterRegistry registry) {
this.orderCounter = Counter.builder("orders.created")
.description("생성된 주문 수")
.tag("type", "online")
.register(registry);
this.orderTimer = Timer.builder("orders.processing.time")
.description("주문 처리 시간")
.register(registry);
}
public void placeOrder(Order order) {
Timer.Sample sample = Timer.start();
try {
// 주문 처리
orderCounter.increment();
} finally {
sample.stop(orderTimer);
}
}
}
Micrometer는 Spring Boot의 메트릭 추상화 계층이다 — Prometheus, Datadog, CloudWatch 등 다양한 백엔드로 메트릭을 내보낼 수 있다. "메트릭 API를 한 번 작성하면 모니터링 시스템을 바꿔도 코드가 그대로" 유지된다. (Micrometer Reference)
Spring Boot 4.0 — 구조화된 로깅과 관측성
Spring Boot 4.0은 구조화된 로깅(ECS, GELF)과 분산 추적(OpenTelemetry) 통합을 강화했다:
# Spring Boot 4 — 분산 추적 + 구조화된 로깅
logging:
structured:
format:
console: ecs # JSON 형식 로그
management:
tracing:
sampling:
probability: 1.0 # 100% 샘플링 (개발용)
구조화된 로깅 + 메트릭 + 분산 추적(Tracing)의 세 가지 관측성(Observability) 기둥이 Spring Boot 4.0에서 통합 지원된다. ELK(로그) + Prometheus(메트릭) + Jaeger/Zipkin(추적) 조합으로 마이크로서비스 환경을 완전히 관측할 수 있다.
실습 — 헬스 체크 시뮬레이션
// Spring Boot 4 / Java 25 — HealthCheckDemo.java
import java.util.*;
public class HealthCheckDemo {
record HealthStatus(String component, String status, String detail) {}
public static void main(String[] args) {
List<HealthStatus> checks = List.of(
new HealthStatus("db", "UP", "PostgreSQL 연결 정상"),
new HealthStatus("disk", "UP", "여유 공간 20GB"),
new HealthStatus("redis", "DOWN", "연결 타임아웃"),
new HealthStatus("ping", "UP", null)
);
boolean allUp = checks.stream().allMatch(c -> c.status().equals("UP"));
String overall = allUp ? "UP" : "DOWN";
System.out.println("전체 상태: " + overall);
checks.forEach(c ->
System.out.println(" " + c.component() + ": " + c.status()
+ (c.detail() != null ? " (" + c.detail() + ")" : "")));
}
}
java HealthCheckDemo.java
전체 상태: DOWN
db: UP (PostgreSQL 연결 정상)
disk: UP (여유 공간 20GB)
redis: DOWN (연결 타임아웃)
ping: UP
확인할 것: 하나의 컴포넌트(Redis)가 DOWN이면 전체 상태가 DOWN이 된다. Kubernetes가 이 엔드포인트를 주기적으로 체크하여 unhealthy 판정 시 파드를 재시작한다.
관리 포트 분리 — 보안 강화
# Spring Boot 4 / Java 25 — Actuator를 별도 포트로
management:
server:
port: 9090 # 애플리케이션(8080)과 다른 포트
endpoints:
web:
exposure:
include: "*"
관리 엔드포인트를 별도 포트(9090)로 분리하면, 외부 인터넷에 노출되는 애플리케이션 포트(8080)와 내부 관리 포트를 분리할 수 있다. K8s에서 관리 포트만 ClusterIP로 제한하여 보안을 강화한다.
요약 — 이 글의 결론
- Actuator는 운영 도구(헬스 체크, 메트릭, 환경 정보)를 자동 제공한다.
spring-boot-starter-actuator추가만으로 활성화된다. /actuator/health로 헬스 상태를 확인한다. DB, 디스크, Redis 등 컴포넌트별 상태를 자동 검사. Kubernetes와 결합하여 자동 복구./actuator/metrics로 JVM, DB 풀, HTTP 지연 등을 모니터링한다. 핵심 메트릭: 힙 사용량, DB 연결 풀 활성 수, HTTP p99 지연.- Prometheus + Grafana로 메트릭 대시보드를 구축한다.
/actuator/prometheus엔드포인트로 Prometheus가 스크랩. Micrometer로 메트릭을 백엔드 독립적으로 작성. - Spring Boot 4.0은 구조화된 로깅(ECS/GELF)과 분산 추적(OpenTelemetry)을 통합 지원한다. 관측성의 3축(로그, 메트릭, 추적)이 Spring Boot 하나로 통합.
생각해 볼 문제
/actuator/env가 비밀번호를 마스킹하는 방식은? 실제 값을 보려면 어떻게 하는가?- Micrometer의
Timer와@Timed어노테이션의 차이는? 각각 언제 쓰는가? - Kubernetes Liveness Probe와 Readiness Probe를
/actuator/health에 연결할 때의 베스트 프랙티스는? - Spring Boot 4.0의 구조화된 로깅에서 trace ID/span ID가 자동으로 로그에 포함되는 원리는?
- Actuator 엔드포인트를 별도 관리 포트(예: 9090)로 분리하는 이유는?
- Micrometer의
Counter,Timer,Gauge각각의 용도와 사용 시나리오를 설명하라.
참고
- Spring Boot 4.0 - Actuator - 접근 2026-07-10
- Spring Boot 4.0 - Health - 접근 2026-07-10
- Spring Boot 4.0 - Metrics - 접근 2026-07-10
- Micrometer Reference - 접근 2026-07-10
분산 추적(Tracing) — OpenTelemetry 통합
Spring Boot 4.0은 OpenTelemetry 기반 분산 추적을 통합 지원한다. 마이크로서비스 간 요청 흐름을 trace ID로 추적할 수 있다.
7. Spring Boot 4.0과 이전 버전(Spring Boot 3.x)의 가장 큰 차이점은 무엇인가? 마이그레이션 시 주의할 점은?
8. 이 글에서 다룬 개념을 실제 프로젝트에 적용할 때 가장 먼저 고려해야 할 것은?
- OpenTelemetry Java - 접근 2026-07-10
- Spring Boot 4.0 Observability - 접근 2026-07-10
- Spring Boot 4.0 Reference - 접근 2026-07-10
'Develop Artifacts > Spring Boot' 카테고리의 다른 글
| SpringBoot - 10. deployment (0) | 2026.07.12 |
|---|---|
| SpringBoot - 09. config profile (0) | 2026.07.12 |
| SpringBoot - 07. security (0) | 2026.07.12 |
| SpringBoot - 06. testing (0) | 2026.07.12 |
| SpringBoot - 05. spring-data-jpa (0) | 2026.07.12 |
