Contents
see List운영 중인 Spring Boot 서비스에 관측성이 필요한 이유
API가 느려졌다는 문의를 받은 뒤 서버에 접속해 로그를 찾기 시작하면 원인을 좁히는 시간이 길어집니다. CPU 사용률만으로는 데이터베이스 대기, 외부 API 지연, 커넥션 풀 고갈, JVM 메모리 압박을 구분하기 어렵습니다. Spring Boot Actuator와 Micrometer를 기본 구성에 넣으면 애플리케이션의 상태를 수치와 헬스 체크로 확인할 수 있습니다.
목표는 모든 값을 수집하는 것이 아니라 장애와 성능 저하를 빠르게 판단하는 것입니다. 운영자가 먼저 봐야 할 범주는 요청 지연 시간, 오류 비율, JVM과 프로세스 자원, HTTP 및 데이터베이스 연결 상태, 외부 의존성 상태입니다. 이 문서는 Prometheus가 메트릭을 수집하고 Grafana가 시각화하는 일반적인 구조를 기준으로 설명합니다.
의존성과 Actuator 노출 범위 설정
Spring Boot 프로젝트에 Actuator와 Prometheus 레지스트리를 추가합니다. Spring Boot가 관리하는 의존성 버전을 사용하면 Micrometer 버전을 별도로 고정할 필요가 없습니다. actuator 엔드포인트는 관리 목적의 인터페이스이므로 전체를 외부에 공개하지 말고 필요한 항목만 노출합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>다음 설정은 health, info, prometheus만 웹으로 노출하고, 헬스 상세 정보는 내부 인증 사용자에게만 제공하는 예시입니다. 프로덕션에서 management 포트를 애플리케이션 공개 포트와 분리하거나 사설 네트워크와 인그레스 정책으로 제한하면 공격 표면을 더 줄일 수 있습니다.
management:
endpoints:
web:
exposure:
include: health,info,prometheus
endpoint:
health:
show-details: when_authorized
metrics:
tags:
application: order-api
server:
port: 8081Prometheus는 일반적으로 /actuator/prometheus를 일정 주기로 읽습니다. 이 주소를 인터넷에 직접 공개하지 말고 Prometheus 서버만 접근할 수 있게 방화벽, 네트워크 정책 또는 인증 프록시를 적용합니다. health 엔드포인트도 로드밸런서의 liveness, readiness 확인 용도와 사람이 보는 상세 진단 용도를 분리해 설계하는 편이 안전합니다.
대시보드에 넣을 핵심 지표
- HTTP 요청: http.server.requests의 요청 수, 4xx·5xx 비율, p95·p99 지연 시간을 URI와 상태 코드 기준으로 봅니다.
- JVM: jvm.memory.used, jvm.gc.pause, jvm.threads.live를 통해 메모리 압박과 긴 GC 정지를 확인합니다.
- 프로세스: process.cpu.usage, system.cpu.usage, process.uptime은 애플리케이션과 호스트의 자원 문제를 구분하는 데 유용합니다.
- 커넥션 풀: jdbc.connections.active, jdbc.connections.max 또는 사용하는 풀의 활성·대기 지표로 데이터베이스 병목을 찾습니다.
- 외부 호출: 외부 HTTP 클라이언트의 지연 시간과 오류 수를 별도 태그로 기록해 특정 공급자 장애를 빠르게 분리합니다.
URI 태그에는 주문 번호나 사용자 ID처럼 값이 계속 달라지는 식별자를 넣으면 안 됩니다. 이런 고유값은 시계열 수를 폭증시켜 Prometheus 메모리 사용량과 질의 시간을 악화시킵니다. 경로 변수는 템플릿 경로로 정규화하고, 필요한 분류는 제한된 값 목록을 가진 operation, client, result 같은 태그로 설계합니다.
업무 지표를 직접 추가하는 방법
인프라 지표만으로는 결제 실패나 재고 동기화 지연 같은 업무 장애를 알기 어렵습니다. 중요한 처리 결과는 Counter, 처리 중인 작업 수는 Gauge, 소요 시간은 Timer로 기록합니다. 아래 예시는 결제 승인 결과를 제한된 result 태그로 집계하는 서비스 코드입니다.
@Service
public class PaymentMetrics {
private final MeterRegistry registry;
public PaymentMetrics(MeterRegistry registry) {
this.registry = registry;
}
public void recordApproval(String result) {
Counter.builder("payment.approval.count")
.tag("result", result)
.register(registry)
.increment();
}
}result 값은 success, declined, error처럼 미리 정한 작은 집합만 허용해야 합니다. 예외 메시지, 주문 ID, 고객 이메일을 태그에 넣으면 개인정보 노출 위험과 카디널리티 문제가 동시에 생깁니다. 업무 지표에는 숫자만 기록하고, 개별 요청의 상세 원인은 로그와 추적 ID에서 찾는 역할 분리가 필요합니다.
알람은 증상과 원인을 함께 설계한다
알람을 CPU 80% 하나로 만들면 배치 작업 같은 정상 상황에서도 경보가 울립니다. 사용자 영향이 나타나는 증상 지표를 우선으로 잡고, 원인 분석용 지표를 함께 대시보드에 배치합니다. 예를 들어 5분 동안 5xx 비율이 2%를 넘고 요청 수가 일정 수준 이상일 때 경보를 발생시키면 일시적인 소량 오류를 줄일 수 있습니다. p95 지연 시간 증가와 활성 DB 커넥션 증가가 동시에 보이면 데이터베이스 또는 쿼리 병목을 우선 조사할 수 있습니다.
groups:
- name: spring-service
rules:
- alert: ApiServerErrorRateHigh
expr: |
sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
/ sum(rate(http_server_requests_seconds_count[5m])) > 0.02
for: 10m
labels:
severity: warning
annotations:
summary: API 5xx 비율이 10분간 2%를 초과했습니다.분모가 거의 없는 서비스는 오류 한 건으로 비율이 과도하게 커질 수 있으므로 실제 환경에서는 최소 요청 수 조건을 추가합니다. 알람 메시지에는 서비스명, 환경, 대시보드 링크, 대응 순서를 넣고 담당자가 즉시 같은 화면을 열 수 있게 만듭니다. 배포 직후에는 새 버전의 메트릭 이름과 태그가 기존 알람과 호환되는지도 확인합니다.
배포 전 체크리스트
- Actuator 엔드포인트는 필요한 항목만 노출하고 관리 경로 접근을 네트워크 또는 인증으로 제한한다.
- HTTP 지연 시간, 오류율, JVM, 커넥션 풀, 핵심 업무 성공·실패 지표를 대시보드에 연결한다.
- 태그에는 사용자·주문·예외 메시지처럼 무한히 증가하거나 민감한 값을 넣지 않는다.
- 알람은 단일 자원 수치보다 오류율과 지연 시간 같은 사용자 영향 지표를 우선한다.
- 장애 대응 전에 대시보드, 로그, 추적 ID의 연결 경로를 한 번 실제로 점검한다.
관측성은 장애가 난 뒤에 추가하는 도구가 아니라, 배포와 운영의 기본 인터페이스입니다. 적은 수의 의미 있는 지표부터 시작해 경보의 정확도와 대응 시간을 계속 조정하면 Spring Boot 서비스의 상태를 훨씬 예측 가능하게 관리할 수 있습니다.
spring
| No | 작성일 | Title |
|---|---|---|
| 3360 | 2026. 08. 15. | Spring Boot Actuator와 Micrometer로 장애 징후를 먼저 찾는 운영 모니터링 구성 |
| 3328 | 2026. 08. 06. | Spring Boot 예외 처리 표준화 가이드: ProblemDetail로 일관된 API 오류 응답 만들기 |
| 3296 | 2026. 07. 29. | Spring Boot 로그인 API 보안 설계: 세션 없이 JWT를 안전하게 검증하는 방법 |
| 3265 | 2026. 07. 21. | Spring Boot API 장애 원인 빨리 찾기: Actuator와 Micrometer 관측성 구성 가이드 |
| 3238 | 2026. 07. 13. | Spring Boot 안정적인 외부 API 연동: WebClient·Circuit Breaker·Retry를 함께 운영하는 실전 가이드 |
| 3182 | 2026. 07. 04. | Spring Boot 무중단 배포를 위한 Graceful Shutdown과 Readiness Probe 설정 |
| 3137 | 2026. 06. 26. | Spring Security API 권한 설계: 공개 엔드포인트와 관리자 기능을 분리하는 실전 기준 |
| 3081 | 2026. 06. 18. | Spring Boot API 장애 추적을 위한 요청 ID와 관측 로그 설계 |
| 2992 | 2026. 06. 10. | Spring Boot 무중단 배포를 위한 준비 상태 점검과 종료 처리 설계 |
| 2935 | 2026. 06. 02. | Spring Boot Redis 캐시 운영 가이드: TTL, 무효화, 캐시 스탬피드 방지 설계 |