운영 문제는 운영 단계에서 시작되지 않습니다. 대부분의 운영 문제는 설계 단계에서 이미 심어져 있습니다.
운영성을 고려하지 않은 설계의 결과
시스템을 설계할 때 기능 요구사항에 집중합니다. 무엇을 할 수 있어야 하는가. 이것은 당연히 중요합니다.
그러나 운영성—운영 담당자가 시스템을 안전하게 운영할 수 있는가—은 종종 나중으로 미뤄집니다. "일단 돌아가게 만들고 나중에 다듬자"는 접근이 낳는 문제는 예측 가능합니다.
- 장애 발생 시 원인을 파악하기 어려운 구조
- 특정 구성 요소 하나가 전체를 멈추게 하는 단일 장애점
- 확인할 수 없는 상태, 변경할 수 없는 설정
- 운영 담당자가 내부를 이해하지 못하는 블랙박스
이런 시스템은 만들고 나서 고치는 것이 처음부터 잘 만드는 것보다 훨씬 어렵습니다.
운영성을 높이는 설계 원칙
관찰 가능성(Observability). 시스템의 내부 상태를 외부에서 파악할 수 있어야 합니다. 로그, 메트릭, 트레이싱의 세 가지가 모두 필요합니다.
로그는 "무슨 일이 있었는가"를 말해줍니다. 메트릭은 "시스템이 얼마나 잘 작동하고 있는가"를 보여줍니다. 트레이싱은 "하나의 요청이 어떤 경로로 처리됐는가"를 추적합니다.
세 가지가 없는 시스템에서 장애가 나면 운영자는 맹인이 됩니다.
실패 격리(Fault Isolation). 하나의 구성 요소가 실패했을 때 전체 시스템이 영향을 받지 않아야 합니다. 서킷 브레이커, 타임아웃, 폴백 처리가 이를 가능하게 합니다.
"A 서비스가 느려지면 A를 호출하는 B, C, D가 모두 느려진다"는 구조는 한 개의 장애가 연쇄 장애로 번지게 합니다.
설정의 외부화. 운영 환경에 따라 달라지는 값—데이터베이스 접속 정보, 외부 API 주소, 타임아웃 값—을 코드 내부에 하드코딩하지 않습니다. 환경 변수나 설정 파일로 분리하면 코드 변경 없이 운영 설정을 변경할 수 있습니다.
상태 점검 엔드포인트. 시스템이 정상 동작 중인지 확인할 수 있는 헬스체크 엔드포인트를 제공합니다. 단순히 "서버가 살아있다"를 확인하는 수준을 넘어 "데이터베이스에 연결되어 있고, 외부 의존성이 정상이고, 핵심 기능이 작동한다"를 확인해야 합니다.
배포 단위의 최소화. 한 번의 배포에 너무 많은 변경이 포함되면 장애 발생 시 원인을 찾기 어렵습니다. 작고 독립적인 배포 단위를 유지하면 문제가 생겼을 때 어떤 변경이 원인인지 빠르게 파악할 수 있습니다.
운영 친화적 설계 체크리스트
시스템을 설계하거나 검토할 때 확인해야 할 항목입니다.
- 장애 발생 시 원인을 로그에서 찾을 수 있는가?
- 외부 의존성 하나가 실패해도 전체가 멈추지 않는가?
- 코드 배포 없이 운영 설정을 변경할 수 있는가?
- 새 담당자가 시스템 구조를 문서 없이도 파악할 수 있는가?
- 배포를 롤백할 수 있고, 롤백 기준이 명확한가?
- 시스템의 핵심 지표를 모니터링하고 있는가?
기술 부채와 운영성
운영성을 낮추는 설계는 곧 기술 부채가 됩니다. 처음엔 빠르게 만들 수 있어도, 시간이 지날수록 유지보수 비용이 늘어납니다.
운영성이 낮은 시스템일수록 담당자 의존도가 높아집니다. 특정 담당자가 없으면 운영이 되지 않는 시스템은 조직의 리스크입니다.
안정적 운영은 좋은 운영 담당자가 아니라 잘 설계된 시스템에서 나옵니다. 운영성은 기능 요구사항만큼 중요한 설계 기준입니다.