Back to blog
System Design1 min read2025년 8월 24일

복잡도를 늘리지 않고 시스템을 견고하게 만들기

변화 속에서도 안정적으로 버티는 시스템을 만들면서, 모든 계층을 과하게 설계하지 않기 위한 판단 기준을 정리했습니다.

계층별 시스템 경계를 표현한 추상 일러스트

견고함은 보통 재시도, 서킷 브레이커, 격벽, 큐 같은 메커니즘 목록으로 이야기됩니다. 실제로 어려운 부분은 그중 무엇이 정말 필요한지 고르는 일입니다. 추가한 메커니즘은 그 자체로 고장 날 수 있는 구성 요소가 되기 때문입니다.

이미 겪어 본 실패에서 시작하기

가장 값싼 견고함은 이미 관찰한 실패에서 나옵니다. 새 계층을 얹기 전에 최근 장애 다섯 건을 적어 두고, 어떤 메커니즘이 결과를 바꿨을지 물어보세요. 대부분의 팀은 두세 가지 패턴이 실제 실패의 대부분을 덮는다는 걸 발견합니다.

복잡도도 예산처럼 배정하기

모든 추상화에는 유지 비용이 따라옵니다. 새로 합류한 사람의 학습, 디버깅, 업그레이드 경로가 그렇습니다. 복잡도를 총량이 정해진 예산으로 다루세요. 메시지 큐에 예산을 쓰는 결정은 두 번째 캐시 계층을 포기하는 결정과 같습니다.

계층별로 나눈 복잡도 예산
복잡도를 예산으로 다루면 트레이드오프가 암묵적인 상태로 남지 않습니다.

성능 저하 경로를 기본 경로로 만들기

성능 저하를 잘 견디는 시스템에는 공통점이 하나 있습니다. 저하된 경로가 장애 때만 쓰이는 게 아니라 평상시에도 계속 실행된다는 점입니다. 전체 트래픽의 1%를 항상 캐시된 결과로 응답하는 편이, 새벽 3시에 처음 실행되는 폴백보다 훨씬 믿을 만합니다.

오류 예산 계산기

남겨 둘 것

  • 지터와 상한을 갖춘, 일관되게 적용되는 재시도 정책 하나
  • 의존성별 타임아웃을 관리하는 단일 지점
  • 프로세스 생존이 아니라 사용자가 체감하는 동작을 반영하는 헬스 신호
  • 사용자와 맞닿은 모든 화면에 대해 문서화된 저하 모드

나머지는 실제로 겪은 실패를 근거로 제시할 수 있을 때 자리를 얻어야 합니다.

Topics

architecturereliabilitykubernetes

Related work

See the correlation view