//
요즘 개발자를 위한 시스템 설계 수업 · 디렌드라 신하, 테자스 초프라
8장의 후반부는 시스템을 만든 다음의 이야기다. 분산 시스템은 하나의 프로세스를 디버거로 따라갈 수 없으므로, 시스템의 내부 상태를 밖에서 관측할 수 있게 만드는 장치를 처음부터 설계에 포함해야 한다.
로깅은 시스템 상태를 파악하고 문제를 해결하는 가장 기본적인 수단이다. 분산 환경에서 핵심이 되는 것은 중앙 집중형 로깅(Centralized Logging), 즉 여러 기기에서 생성된 로그를 한곳에 모아 저장하는 방식이다.
| 장점 | 내용 |
|---|---|
| 접근성 향상 | 서버마다 SSH로 접속해 파일을 뒤지지 않아도 된다 |
| 상관관계 분석 | 여러 서비스의 로그를 시간축에 함께 놓고 볼 수 있다 |
| 데이터 장기 보관 | 서버 수명과 무관하게 로그를 유지할 수 있다 |
두 번째가 중앙 집중형 로깅의 진짜 이유다. 하나의 요청이 여러 서비스를 거치는 구조에서, 각 서비스의 로그가 각자의 디스크에만 남아 있으면 그 요청이 어디서 실패했는지 재구성할 수 없다.
주요 오픈 소스 도구는 세 가지가 소개된다.
| 도구 | 특징 |
|---|---|
| 로그스태시(Logstash) | 엘라스틱 스택의 구성 요소. 다양한 소스에서 데이터를 수집·변환한 뒤 엘라스틱서치 같은 저장소로 전달 |
| Fluentd | 여러 소스의 데이터를 수집하고 통합하는 다재다능한 데이터 수집기 |
| Graylog | 개방형 표준 기반. 대량의 자동 생성 데이터를 수집·저장하고 실시간 분석을 지원 |
이 다섯 가지 중 실제로 사고 대응 시간을 가장 크게 줄이는 것은 컨텍스트 정보다. 특히 요청 단위의 상관관계 ID를 모든 로그 줄에 넣어 두면, 사용자가 신고한 하나의 실패를 전 서비스에 걸쳐 한 번의 검색으로 추적할 수 있다. 이 ID를 서비스 간에 전달하는 문제가 뒤에 나오는 분산 트레이싱의 컨텍스트 전파와 정확히 같은 문제다.
메트릭은 특정 시간 간격 동안 측정된 데이터를 수치로 표현한 것이다. 로그가 "무슨 일이 있었는가"를 기록한다면, 메트릭은 "지금 어떤 상태인가"를 숫자로 요약한다.
책은 메트릭을 세 종류로 나눈다.
| 종류 | 예시 |
|---|---|
| 시스템 메트릭 | CPU 사용량, 메모리 사용량, 디스크 입출력, 네트워크 입출력 |
| 애플리케이션 메트릭 | 요청 속도, 오류 비율, 응답 시간 |
| 비즈니스 메트릭 | 사용자 가입 수, 주문 건수 등 도메인 관련 항목 |
이 분류가 유용한 이유는 누가 그 숫자를 보는가가 다르기 때문이다. 시스템 메트릭은 인프라 담당자가, 애플리케이션 메트릭은 서비스 개발자가, 비즈니스 메트릭은 제품 담당자가 본다. 대시보드를 하나에 다 몰아넣으면 아무도 자기 숫자를 찾지 못한다.
| 도구 | 특징 |
|---|---|
| 프로메테우스(Prometheus) | 모니터링과 알림을 함께 제공. 다차원 데이터 모델과 PromQL 쿼리 언어. 그래프·대시보드 도구와 통합이 쉽다 |
| 그라파이트(Graphite) | 숫자 시계열 데이터 저장과 그래프 시각화에 특화. 단순한 구조와 높은 확장성 |
| 데이터독(Datadog) | 클라우드 환경 애플리케이션을 모니터링하는 SaaS 기반 서비스 |
"오류율과 지연 시간"이 따로 언급되는 것은 이유가 있다. 구글 SRE의 네 가지 골든 시그널이 지연 시간(Latency), 트래픽(Traffic), 오류(Errors), 포화도(Saturation)인데, 이 중 사용자가 실제로 체감하는 것이 앞의 셋이다. 그리고 지연 시간은 반드시 평균이 아니라 백분위(p95, p99)로 봐야 한다. 평균은 소수의 극단적으로 느린 요청을 숨긴다.
알림 설계의 핵심은 민감도와 정확성 사이의 균형이다. 너무 민감하면 거짓 경보가 쏟아지고, 너무 둔감하면 실제 장애를 놓친다.
책이 제시하는 판단 기준은 세 가지다.
두 번째 기준이 가장 실용적이다. 받아도 할 수 있는 일이 없는 알림은 알림이 아니라 소음이다. 조치할 방법이 없다면 그것은 대시보드에 있어야 할 지표이고, 알림으로 만들 이유가 없다.
도구로는 프로메테우스의 구성 요소인 알림 매니저(Alertmanager), 데이터 기반 조건으로 알림을 만들 수 있는 그라파나(Grafana), 그리고 모니터링 도구와 연동해 알림을 중앙에서 관리하는 페이저듀티(PagerDuty)를 든다. 페이저듀티는 오픈 소스가 아니지만 프로메테우스나 그라파나와 쉽게 연동된다.
모범 사례는 짧고 명확하다.
"알림을 너무 많이 발생시키지 말 것"은 표현이 온건하지만 실제로는 가장 중요한 규칙이다. 알림 피로(Alert Fatigue)가 쌓이면 팀이 알림을 무시하기 시작하고, 그 순간 알림 체계 전체가 무력화된다. 알림을 추가하는 것보다 쓸모가 없어진 알림을 정기적으로 지우는 일이 더 어렵고 더 중요하다.
분산 트레이싱은 하나의 요청이 여러 서비스와 서버를 거치는 과정을 추적하는 기법이다. 요청이 처리되는 각 단계를 스팬(Span) 으로 기록하고, 스팬이 모여 요청 전체의 흐름을 보여주는 트레이스(Trace) 를 구성한다.
하나의 트레이스는 스팬들이 시간축 위에 겹쳐 쌓인 형태로 보인다.
trace_id = a1b2c3
0ms 320ms
|-----------------------------------------------------------|
[API 게이트웨이: 요청 처리 ] 320ms
[사용자 서비스: 인증 확인 ] 70ms
[주문 서비스: 주문 조회 ] 160ms
[데이터베이스: SELECT 쿼리 ] 100ms
각 막대가 하나의 스팬이고, 스팬은 부모 스팬의 ID를 들고 있어 호출 관계가 트리로 복원된다. 위 예시에서는 전체 320ms 중 100ms가 데이터베이스 쿼리에서 소모됐다는 사실이 한눈에 드러난다.
이 구조가 주는 이점은 세 가지다.
메트릭과의 차이가 여기서 갈린다. 메트릭은 "주문 API의 p99 지연 시간이 2초"라고 알려주지만, 그 2초가 어디서 발생하는지는 알려주지 않는다. 트레이싱은 그 2초를 서비스별로 쪼개 보여준다.
| 도구 | 특징 |
|---|---|
| 예거(Jaeger) | 우버가 개발한 오픈 소스 분산 트레이싱 시스템. 분산 컨텍스트 전파, 트랜잭션 모니터링, 근본 원인 분석, 성능 최적화 기능 |
| 집킨(Zipkin) | 마이크로서비스의 지연 문제 분석을 위해 각 서비스의 요청 처리 시간을 수집·관리. 직관적인 인터페이스로 요청 흐름을 시각화 |
| 오픈텔레메트리(OpenTelemetry) | 분산 트레이스와 메트릭 데이터를 수집하는 API, 라이브러리, 에이전트, 수집기를 통합 제공하는 관측 프레임워크 |
오픈텔레메트리가 앞의 둘과 성격이 다르다는 점을 짚어 둘 만하다. 예거와 집킨은 트레이스를 저장하고 보여주는 백엔드이고, 오픈텔레메트리는 애플리케이션에서 데이터를 뽑아내는 계측 표준이다. 오픈텔레메트리로 계측해 두면 백엔드를 예거에서 다른 것으로 바꿀 때 애플리케이션 코드를 건드리지 않아도 된다.
두 번째가 분산 트레이싱 도입에서 실제로 가장 까다로운 부분이다. HTTP 헤더로 트레이스 ID를 넘기는 것은 쉽지만, 메시지 큐를 거치는 비동기 경로나 배치 작업에서 컨텍스트를 이어 붙이는 일은 별도 작업이 필요하다.
로그, 메트릭, 트레이스는 흔히 관측 가능성의 세 기둥으로 불린다. 각자 답하는 질문이 다르다.
| 신호 | 답하는 질문 | 조사 순서에서의 역할 |
|---|---|---|
| 메트릭 | 무언가 잘못되었는가? | 문제의 존재와 규모를 알린다 |
| 트레이스 | 어디서 잘못되었는가? | 문제의 위치를 좁힌다 |
| 로그 | 왜 잘못되었는가? | 그 지점의 상세 원인을 밝힌다 |
세 신호를 이 순서로 쓸 수 있게 만드는 것이 실무의 목표다. 메트릭 알림에서 트레이스로, 트레이스에서 해당 스팬의 로그로 클릭 한 번에 이동할 수 있으려면, 세 신호가 공통 ID로 연결되어 있어야 한다. 로깅 절에서 나온 "로그에 컨텍스트 정보 포함하기"가 결국 여기로 이어진다.
8장은 API 설계에서 관측 가능성까지 폭넓게 다루고, 책이 스스로 요약한 여섯 가지 실천 항목으로 마무리한다. 적절한 API 설계 선택, API 보안 최우선 고려, 중앙 집중형 로깅 구현, 핵심 메트릭 모니터링, 구체적이고 실용성 있는 알림 설계, 분산 트레이싱 활용.
관측 가능성 부분은 도구 목록과 모범 사례 나열 중심이라 깊이는 얕지만, 각 신호가 무엇을 위해 존재하는지는 명확하게 구분해 준다. 특히 알림 설계에서 "실행 가능성"을 기준으로 제시한 것과, 트레이싱에서 컨텍스트 전파를 별도로 강조한 것은 실제 운영 경험이 반영된 대목으로 읽힌다.
건축과 운영을 같은 장에 묶어 놓은 구성도 의미가 있다. 관측 가능성은 시스템을 다 만든 다음에 얹는 부가 기능이 아니라, API를 설계하는 시점에 요청 ID를 어떻게 흘릴지 함께 결정해야 하는 문제라는 점이 드러난다.
이 글이 도움이 되셨나요?