← 블로그 목록

Developer Knowledge

개발자가 알아야 할 지식: 그레이스풀 디그라데이션, 일부가 망가져도 서비스는 계속되어야 한다

장애를 완전히 없앨 수 없을 때 핵심 기능부터 지키는 설계 원칙과 실무 체크리스트를 정리합니다.

Amazon Web Services
  • 개발자가 알아야 할 지식
  • Reliability
  • Architecture
  • Operations

완벽히 안정적인 시스템은 없습니다. 그래서 좋은 시스템은 실패하지 않는 척하기보다, 실패했을 때 무엇을 계속 제공할지 미리 정합니다.

왜 개발자가 알아야 하나

실무 서비스는 결제, 검색, 추천, 알림, 이미지 처리, 분석 로그처럼 서로 다른 중요도를 가진 기능으로 이루어집니다. 모든 기능이 같은 순간에 같은 수준으로 살아 있어야 한다고 가정하면 작은 장애도 전체 장애가 됩니다.

그레이스풀 디그라데이션은 장애 상황에서 핵심 사용자 여정을 우선 지키는 사고방식입니다. 추천 서버가 느리면 기본 목록을 보여주고, 이미지 변환이 실패하면 원본 이미지를 보여주며, 분석 이벤트 전송이 막혀도 사용자의 저장 버튼은 동작하게 만드는 식입니다.

이 개념은 운영팀만의 일이 아닙니다. 프론트엔드의 로딩 상태, 백엔드의 타임아웃, 데이터베이스의 fallback query, 배포 전략, 제품 요구사항 우선순위가 모두 연결됩니다. 개발자가 이 원칙을 모르면 장애를 “예외 상황”으로만 처리하고, 사용자가 실제로 겪는 실패 경험은 방치하기 쉽습니다.

핵심 개념

핵심은 기능을 중요도에 따라 나누는 것입니다. 반드시 성공해야 하는 경로, 실패해도 대체 가능한 경로, 조용히 포기해도 되는 경로를 구분해야 합니다. 이 구분이 없으면 코드에서는 모든 예외가 같은 무게를 갖습니다.

두 번째는 의존성의 실패 모드를 명시하는 것입니다. 외부 API가 느릴 때 기다릴지, 캐시를 쓸지, 빈 값을 반환할지, 사용자에게 재시도를 안내할지 정해야 합니다. 장애 대응은 런타임의 즉흥 판단이 아니라 설계의 결과여야 합니다.

세 번째는 관측 가능성입니다. fallback이 동작했다고 해서 장애가 사라진 것은 아닙니다. 사용자는 큰 불편 없이 지나가더라도 시스템은 degraded 상태를 기록하고 알림을 보내야 합니다. 조용한 fallback만 있고 지표가 없으면 장애가 오래 숨어 있습니다.

작은 예시 또는 체크리스트

예를 들어 상품 상세 페이지가 가격, 재고, 추천, 리뷰, 배송 예상일을 각각 다른 서비스에서 가져온다고 해봅시다. 구매 버튼과 가격은 핵심이고, 추천 상품은 보조 기능입니다. 추천 API가 실패했을 때 전체 페이지를 500으로 만드는 것은 사용자의 구매 여정을 불필요하게 망가뜨립니다. 대신 추천 영역만 숨기고, 지표에는 추천 API fallback 발생률을 남기는 편이 낫습니다.

  • 이 기능이 실패하면 사용자가 정말 작업을 완료할 수 없는가?
  • 외부 의존성이 느릴 때 전체 요청 타임아웃을 잡아먹지 않는가?
  • 캐시, 기본값, 이전 성공 결과처럼 쓸 수 있는 대체 경로가 있는가?
  • fallback이 발생했음을 로그와 지표로 확인할 수 있는가?
  • degraded 상태에서 사용자에게 보여줄 문구가 제품적으로 정리되어 있는가?
  • 테스트가 정상 경로뿐 아니라 의존성 실패 경로도 검증하는가?

실무에서 자주 생기는 오해

  • “fallback이 있으면 장애가 아니다”는 오해가 있습니다. fallback은 사용자 피해를 줄이는 장치이지 원인 해결이 아닙니다. 발생률이 높아지면 반드시 알림과 후속 조치가 필요합니다.

  • “아무 값이나 기본값으로 주면 된다”도 위험합니다. 가격, 권한, 결제, 의료 정보처럼 틀린 값이 빈 값보다 더 해로운 영역이 있습니다. 이런 곳에서는 실패를 숨기지 말고 안전하게 막아야 합니다.

  • “프론트에서 예쁘게 처리하면 된다”는 생각도 절반만 맞습니다. 화면은 부드러워 보여도 서버가 계속 느린 의존성을 기다리면 비용과 지연은 그대로 쌓입니다. 타임아웃과 회로 차단 같은 백엔드 정책이 함께 필요합니다.

  • “나중에 장애가 나면 붙이자”는 접근은 늦습니다. 장애가 난 뒤에는 어떤 기능을 희생해도 되는지 제품 판단을 차분히 하기 어렵습니다. 중요한 경로일수록 설계 단계에서 degraded mode를 정해야 합니다.

오늘 바로 적용해보기

오늘 코드 리뷰에서 외부 API 호출 하나를 골라 “이 호출이 실패하면 사용자는 무엇을 보게 되는가”를 물어보세요. 답이 “전체 실패”라면 정말 그래야 하는 기능인지 다시 나눠볼 수 있습니다.

운영 대시보드에는 성공률뿐 아니라 fallback 발생률을 추가해보세요. 정상 응답 200만 보면 서비스가 괜찮아 보여도, 실제로는 보조 기능이 계속 빠지고 있을 수 있습니다.

제품 문서에는 핵심 기능과 보조 기능을 구분해두세요. 기술적인 장애 대응처럼 보여도 결국 어떤 사용자 경험을 지킬지의 문제입니다.

더 알아보기

오늘의 takeaway

좋은 장애 대응은 모든 것을 살리는 기술이 아니라, 망가진 순간에도 무엇을 반드시 살릴지 미리 정해두는 설계입니다.