이전 글에서는 CloudWatch와 Grafana를 활용하여
EC2 인프라 지표 및 로그 기반 모니터링 환경을 구축한 과정을 정리했다.
이번에는 한 단계 더 나아가,
“애플리케이션 성능을 수치로 측정하고,
장애를 자동 감지하며,
비용까지 함께 모니터링하는 구조”
를 구성한 과정을 정리한다.
1. 왜 애플리케이션 메트릭이 필요했을까?
CloudWatch 기반 인프라 모니터링으로는 다음을 알 수 있었다.
- CPU 사용량
- 네트워크 트래픽
- 인스턴스 헬스 상태
- 로그 기반 에러 발생
하지만 여전히 부족했다.
예를 들어 이런 질문에는 답할 수 없었다.
- 현재 초당 요청 수는 얼마나 되는가?
- 평균 응답시간은 얼마인가?
- 사용자가 체감하는 성능은 괜찮은가?
- 서버는 살아있지만 API는 느려진 건 아닌가?
이를 해결하기 위해 Prometheus 기반 애플리케이션 메트릭 수집을 추가했다.
2. Prometheus 기반 API 메트릭 수집
2-1. Spring Boot 설정
Spring Boot에 Actuator + Micrometer를 추가하고
Prometheus endpoint를 활성화했다.
management.endpoints.web.exposure.include=health,info,prometheus,metrics management.metrics.tags.application=qroad-api
management.metrics.distribution.percentiles-histogram.http.server.requests=true
특히 중요한 설정은 다음이었다.
management.metrics.distribution.percentiles-histogram.http.server.requests=true
이 설정이 없으면 p95 latency 계산에 필요한 histogram bucket이 생성되지 않는다.
2-2. Prometheus 서버 구성
Docker로 Prometheus를 실행하고,
Spring 서버의 /actuator/prometheus 엔드포인트를 scrape하도록 설정했다.
scrape_configs:
- job_name:"qroad-api"
metrics_path:"/actuator/prometheus"
static_configs:
- targets: ["172.17.0.1:8080"]
이를 통해 API 레벨의 메트릭을 수집할 수 있게 되었다.
3. Grafana에서 애플리케이션 성능 시각화
Prometheus를 Data Source로 추가한 후 다음 패널을 구성했다.
3-1. Application 상태 확인
up{job="qroad-api"}
값이 1이면 정상, 0이면 애플리케이션 비정상.
CloudWatch StatusCheck와의 차이점은 다음과 같다.
- CloudWatch → EC2 인스턴스 생존 여부
- Prometheus up → Spring 애플리케이션 생존 여부
즉, 서버는 살아있지만 애플리케이션이 죽은 상황을 감지할 수 있다.
3-2. RPS (Requests Per Second)
rate(http_server_requests_seconds_count[1m])
현재 초당 요청 수를 확인할 수 있다.
트래픽 급증 여부나 부하 상황을 파악하는 데 유용하다.
3-3. 평균 응답시간
단순 평균 응답시간을 통해 기본적인 처리 속도를 확인했다.
하지만 평균값은 일부 느린 요청을 숨길 수 있다는 한계가 있었다.
3-4. p95 Latency
이를 보완하기 위해 p95 지표를 추가했다.
histogram_quantile(0.95,
sum(rate(http_server_requests_seconds_bucket{job="qroad-api"}[5m])) by (le)
)
p95는 전체 요청 중 95%가 이 시간 이내에 처리된다는 의미다.
즉, 대부분의 사용자가 체감하는 실제 성능을 나타낸다.
실무에서 평균보다 p95가 더 중요하게 다뤄지는 이유를 직접 체감할 수 있었다.
4. 알람 시스템 구축 (Discord 연동)
단순히 대시보드를 “보는 것”만으로는 부족하다고 판단했다.
그래서 다음 조건을 설정했다.
p95 latency > 1초
Grafana Alert Rule을 구성하고,
Discord Webhook을 통해 알림이 오도록 설정했다.
이로써:
- 성능 저하 자동 감지
- 사용자 영향 가능성 조기 대응
이 가능해졌다.
모니터링이 단순 시각화를 넘어
“운영 대응 체계”로 확장된 순간이었다.
5. AWS 비용 모니터링 추가
운영에서 빼놓을 수 없는 요소는 비용이다.
CloudWatch Billing 메트릭을 활용하여
다음 항목을 시각화했다.
- 총 예상 월 비용
- EC2 비용
- RDS 비용
- S3 비용
Namespace:
AWS/Billing
Metric:
EstimatedCharges
Region은 반드시 us-east-1이어야 한다는 점도 확인했다.
이를 통해 리소스 사용량뿐 아니라
비용 추이까지 함께 확인 가능한 대시보드를 완성했다.
6. 최종 모니터링 구조
현재 구성은 다음과 같다.
🔹 Infra Layer
- CPU
- Network
- Instance Health
- Billing 비용
🔹 Application Layer
- up (서비스 생존)
- RPS
- 평균 응답시간
- p95 latency
- 500 에러율
🔹 Log Layer
- 전체 로그
- ERROR 추이
- 500 에러 로그
🔹 Alert Layer
- p95 기준 Discord 알람
완성화면

- API와 금액이 잘 나오는것을 확인했어.
- 아직은 사용자가 없는 서비스라 수치가 작지만 실제 운영을 시작하면 큰 수치가 보일것으로 기대하고 있다.

- 알람도 잘 오는것을 확인하였다.
마무리
이번 확장 작업을 통해 느낀 점은 명확했다.
“운영은 코드보다 관측이 먼저다.”
서버를 배포하는 것과
서비스를 운영하는 것은 완전히 다른 문제였다.
- 성능을 수치로 이해하고
- 장애를 자동으로 감지하며
- 비용까지 함께 추적하는 구조를 설계하면서
운영의 관점을 직접 경험할 수 있었다.
이 글은 1편(CloudWatch 기반 인프라/로그 모니터링)과 이어지는 확장편이다.
'💻 프로젝트 > QRoad' 카테고리의 다른 글
| 서버 git pull 배포에서 GHCR 기반 Docker 배포로 전환한 기록 (0) | 2026.03.30 |
|---|---|
| AWS 기반 운영 모니터링 환경 구축기 (EC2 + CloudWatch + Grafana) - 1편 (0) | 2026.02.19 |
| 3분 이상 걸리는 기사 발행 API를 Job 기반 비동기로 전환하며 고민한 것들 (0) | 2026.02.16 |