오피사이트 장애 발생 시 대처 가이드
서비스가 멈추는 순간은 항상 갑작스럽다. 접속이 안 되고, 결제창이 멈추고, 고객 문의가 폭주한다. 장애는 규모와 업종을 가리지 않는다. 차이는 준비 정도와 대응 속도다. 여러 차례의 새벽 장애 전개를 겪으며 배운 것은, 기술만으로는 위기를 지나갈 수 없고, 조직과 절차, 평소의 습관이 결국 다운타임을 단축한다는 사실이다. 오피사이트 운영자와 실무자에게 필요한 실전형 대처 가이드를, 준비 단계부터 포스트모템까지 한 호흡으로 정리한다. 여기서 말하는 원칙은 특정 스택에 한정되지 않는다. 그러나 예시를 들 때는 웹서버, 데이터베이스, 캐시, WAS 같은 일반적인 구성으로 설명한다. 운영자 커뮤니티나 오피가이드 레벨의 내부 문서에서 이미 쓰이는 표현도 그대로 차용한다.
무엇이 ‘장애’인가, 어디서부터 기록할 것인가
장애 판단 기준이 모호하면 의사결정이 늦어진다. 단순히 에러율이 올랐다는 이유만으로 전사 알림을 울릴 필요는 없지만, 지표가 회복 불가능한 궤적을 보이는데도 관성적으로 지켜보는 건 더 위험하다. 운영 환경에서 쓰기 좋은 기준은 다음과 같다. SLO 기반의 주요 지표가 연속된 두 개의 측정 구간에서 임계치를 초과한 경우, 또는 사업적으로 치명적인 트랜잭션(로그인, 결제, 예약, 콘텐츠 열람 등)이 3분 이상 실패율 5퍼센트 이상을 유지하는 경우, 장애로 선언한다. 선언 시점부터 모든 조치와 판단을 기록해야 한다. 누가 어떤 명령을 실행했고, 어떤 설정을 바꿨는지, 각 타임스탬프를 남기지 않으면 포스트모템은 형식적 회고로 끝난다.
장애를 정의할 때 기술 지표만 보지 말고 고객 관점 지표를 함께 둬야 한다. 평균 응답시간 800ms가 내부적으로는 문제가 없어 보여도, 특정 단말의 이미지 로딩 실패가 고객의 체감 경험을 무너뜨릴 수 있다. 실제로 모바일 3G 구간에서만 발생한 이미지 CDN 서빙 이슈를, 서버 CPU가 여유롭다는 이유로 한 시간 넘게 놓친 사례가 있다. 오피사이트 같은 트래픽 가변성이 큰 환경에서는 체감형 지표가 더 빨리 신호를 준다.
알림, 관측, 책임자 지정, 이 세 가지가 1분을 살린다
관측과 알림의 설계는 도구 선택보다 임계치와 라우팅 설계가 더 중요하다. 알림은 적어야 한다. 신뢰도가 떨어지는 알림은 결국 음소거된다. 서비스 레벨에서 최소 4가지 라인을 제안한다. 가용성, 에러율, 응답시간, 핵심 트랜잭션 성공률. 여기에 시스템 레벨에서는 CPU 스틸타임, 디스크 IOPS 대기, 메모리 OOM, 네트워크 패킷 드롭 같은 신호를 더한다. 로그는 정제된 형태로 수집해야 한다. 원시 로그만 쌓아두면 장애 시점에 필요한 검색이 늦어진다. 가장 많이 쓰는 쿼리 패턴을 미리 저장해 둔다. 예를 들어 “최근 10분 5xx 비율 상위 엔드포인트”, “특정 사용자 그룹 타임아웃 발생 건수” 같은 쿼리다.
장애 대응 시 역할은 명확할수록 좋다. Incident Commander 한 명, 커뮤니케이션 담당 한 명, 드라이버(실행 담당) 한 명. 작은 조직에서는 한 사람이 두 역할을 겸할 수 있지만, 말하는 사람과 키보드를 잡는 사람을 분리하면 판단속도가 오른다. 슬랙이나 메신저 채널은 사전에 정하고, 전용 브리지 룸을 열어 대화를 한곳에 모은다. 장애 중에는 DM으로 빠지는 대화가 가장 위험하다. 그 정보가 기록에 남지 않고, 회복 이후에도 같은 실수가 반복된다.
장애를 줄이는 설계의 습관
오피사이트는 트래픽 급증과 급감을 반복한다. 설계는 대체로 스파이크와 홀리데이 시즌을 기준으로 한다. 평균 트래픽에 맞추지 말고, 상위 5퍼센트 구간을 견딜 수 있도록 버퍼를 둬야 한다. 단, 과도한 과금과 연결되면 현실적으로 불가능해진다. 실제로는 오토스케일링의 상한과 하한을 계절별 프로파일로 분리해 운영한다. 평상시 하한을 낮추되, 상한은 예측에 따라 번들로 잡고, 외부 캐시와 CDN으로 정적인 리소스와 일부 API 응답을 프런트에서 흡수한다. 로그인과 결제 같은 상태성 트랜잭션은 절대 캐시에 의존하지 말고, 리드 트래픽 중심의 엔드포인트에서 캐시 히트율을 70에서 85퍼센트까지 올리는 것이 현실적인 목표다.
단일 장애 지점을 줄이는 방법은 고전적이지만 여전히 가장 효과적이다. DNS는 이중화하고, 헬스체크를 적극적으로 사용하며, L4/L7 로드밸런서를 이중화한다. 데이터베이스는 리더 - 리플리카 구조를 기본으로 하고, 장애 전환 시 트랜잭션 유실 가능성과 읽기 정합성 저하를 명확히 이해해야 한다. 특히 쓰기 집중 구간에서 멱등성을 보장하지 않은 API는 재시도에 취약하다. 몇 해 전 카드 결제 API가 30초 지연되면서 클라이언트가 3회 재시도를 날려 중복 결제가 발생한 사례가 있었다. 서버는 에러를 반환하지 않았고, 클라이언트는 타임아웃을 오판했다. 이런 경우 서버와 클라이언트 모두 요청 식별자와 멱등키를 강제해야 한다.
첫 10분, 무엇을 할 것인가
장애 선언 후 첫 10분은 상황을 좁히는 시간이다. 범위를 넓히면 손이 느려진다. 트래픽, 에러율, 핵심 트랜잭션을 동시에 본다. 서버 지표만 보면 네트워크를 놓치고, 애플리케이션 로그만 보면 외부 의존성을 놓친다. 중복 원인 탐색을 피하려면 관찰 순서를 정해둔다. 사용자 체감부터, 외부 의존성, 엣지, 애플리케이션, 데이터 계층 순이다. 고객센터에서 들어오는 케이스가 특정 통신사나 특정 지역에 편중되어 있으면, 내부보다는 ISP 라우팅이나 CDN POP 이슈일 확률이 높다. 반대로 모든 구간에서 5xx가 튄다면, 애플리케이션 배포나 설정 변경을 의심한다.
장애 초기에 흔한 실수는 조용한 롤백이다. 기록과 공지 없이 배포를 되돌리면, 겉으로는 빨리 회복되는 것처럼 보여도 원인 분석이 어려워진다. 롤백은 대체로 정답이지만, 변경 범위를 정확히 아는 경우에만 선택해야 한다. 애매하다면 트래픽을 서서히 줄이는 방식으로 카나리를 되감고, 에러율이 반응하는지 관찰한다. 과거에 무의식적으로 전체 롤백을 했다가, 데이터 마이그레이션 스크립트가 이미 돌아간 상태여서 더 큰 불일치가 생긴 경험이 있다. 데이터 변경을 동반하는 배포에서는 항상 롤백 시나리오를 별도로 적어둬야 한다.
외부 의존성, 계약서보다 빠른 우회로
오피사이트는 대개 여러 외부 서비스를 묶어 고객 경험을 만든다. 결제, 본인인증, SMS, 메일, 맵, 푸시, 광고 SDK, 분석 도구 등, 그중 하나만 어긋나도 코어 플로우가 끊긴다. 계약서의 SLA는 장애 순간에 아무런 위로가 되지 않는다. 대비책은 두 가지다. 기능적 폴백과 공급자 이중화. 기능적 폴백은 예를 들어 본인인증이 지연될 때, 낮은 신뢰의 대체 루트를 임시로 열고 후속 검증을 추가하는 방식이다. 공급자 이중화는 결제나 메시징처럼 대체 가능한 모듈을 두 개 이상 붙이고, 라우팅을 상황에 따라 바꾸는 방식이다. 단, 이중화 자체가 장애의 원인이 될 수 있다. 상태 머신의 복잡도가 올라가고, 실패 모드가 급증한다. 따라서 트래픽의 5에서 10퍼센트만 평소에 세컨더리로 흘려서 냉간 대기 대신 온기 대기를 유지하는 편이 낫다.
과거에 SMS 인증이 특정 시간대에 지연되던 공급자가, 공휴일에는 대기열을 대폭 줄이는 정책으로 바뀌면서 예측이 무너진 적이 있다. 그 이후로는 두 공급자를 동적으로 전환하는 로직을 넣고, 일 단위로 성공률과 평균 전송 시간을 비교해 라우팅 가중치를 조정했다. 계약서 검토보다 이 로그가 실무에는 더 도움이 된다.
데이터베이스, 캐시, 큐, 이 3종의 전형적 장애 패턴
데이터베이스 장애는 대체로 세 가지로 요약된다. 잠금 경합, 커넥션 고갈, 스토리지 병목. 잠금은 대량 업데이트나 스키마 변경 중에 자주 발생한다. 초단기 해결책은 문제 쿼리를 찾아 KILL하고, 적용 중인 DDL이라면 롤백을 택하되 서비스 영향 시간을 계산한다. 커넥션 고갈은 앱단의 커넥션 풀 설정과 밀접하다. 최대 커넥션을 늘리는 것은 지연된 파국일 뿐, 지연이 쌓여 타임아웃이 도미노로 발생한다. 안전한 접근은, 읽기 전용 트래픽을 리플리카로 넘기고, N+1 쿼리를 임시 캐시에 태워 급한 불을 끄는 것이다. 스토리지는 디스크 지연이 20ms를 넘고 IOPS 대기가 생길 때 체감 성능 저하가 빠르게 나타난다. SSD 계층을 추가해도, 쓰기 증폭이 많은 워크로드에서는 금방 한계에 부딪힌다. 장기적으로는 테이블 파티셔닝, 아카이빙, 인덱스 재구성, 쿼리 재작성의 조합이 필요하다.
캐시는 축복이자 함정이다. 높은 히트율을 유지하면 비용과 지연이 함께 줄지만, 캐시 스탬피드는 트래픽 폭탄으로 이어진다. 만료를 한 시점에 몰아두지 말고, 분산 만료를 쓰거나 soft TTL 전략을 쓰는 편이 안전하다. 장애 중에는 캐시 전체 플러시를 금지해야 한다. 감정적으로 시원하지만, 탄산 한 캔에 불을 끄는 격이다. 캐시 클러스터에 파편화가 심해졌다면 재샤딩을 검토하되, 실시간 재분산이 가능한 토폴로지를 미리 준비한다.
큐는 눈에 덜 띈다. 그러나 큐 지연이 상승하면 비동기 작업이 밀리면서 체감 성능과 운영 데이터가 뒤틀린다. 대표적 증상은 알림 발송 지연, 썸네일 생성 지연, 정산 배치 누락이다. 장애 시점에는 소비자 수를 수평 확장하는 것이 즉각적 대응이지만, 메시지 중복 처리 안전성을 반드시 확인한다. 오피사이트의 정산 로직처럼 단 한 번만 처리되어야 하는 작업은 멱등키와 락을 활용해 재처리에도 안전하게 설계해야 한다.
배포와 변경 관리, 결국 사람의 문제
장애의 상당수는 변경에서 시작된다. 코드, 설정, 인프라, 데이터. 무중단 배포 파이프라인을 갖추고도, 피처 플래그의 잘못된 기본값 하나로 지옥문이 열린 사례는 셀 수 없다. 사람은 실수한다. 그래서 절차가 필요하다. 변경은 시간대를 가린다. 고위험 변경은 트래픽이 낮은 시간대에만, 더블 체크 이후 진행한다. 배포 전 체크리스트를 짧고 강하게 만든다. 길면 아무도 보지 않는다. 내 경험상 다음의 5개 문항만 꾸준히 지켜도 사고가 반으로 줄었다.
이 변경으로 영향받는 트랜잭션을 문서화했는가 롤백 절차를 테스트했고, 데이터 마이그레이션의 되감기 전략이 있는가 알림 임계치와 대시보드가 배포 후 상태를 감지하도록 준비됐는가 트래픽을 안전하게 절반으로 나눠 카나리할 수 있는가 비상 연락처와 책임자를 모두 태그했는가
피처 플래그는 현장에서 빛을 발한다. 배포를 되돌리지 않고도 기능을 꺼서 피해를 국소화할 수 있다. 단, 플래그는 쌓인다. 3개월 이상 방치된 플래그는 부채다. 정리 주기를 만드느냐, 장애 때마다 과거 플래그가 뜻하지 않게 작동하느냐의 선택지일 뿐이다.
고객 커뮤니케이션, 조용한 복구가 항상 최선은 아니다
고객은 감지한다. 접속이 느리거나 결제가 실패하면 이미 장애를 체감하고 있다. 모든 장애에 공지를 박는 것은 과도하지만, 체감 영향이 넓거나 지속시간이 10분을 넘길 것으로 보이면 상태 페이지 업데이트를 권한다. 문구는 짧고 구체적으로. 영향 범위, 시작 시각, 현재 조치, 다음 업데이트 시각. “일부 사용자”라는 표현은 신뢰를 떨어뜨린다. 실제 범위를 모르겠다면 조건을 적는다. “안드로이드 앱 6.0 오피가이드 https://xn--o39a11of3ophb790b.isweb.co.kr/ 이하 버전에서 로그인 오류가 발생 중이며, 15분 내 다음 업데이트를 제공하겠습니다.” 같은 문장이다.
보상 정책은 조급하게 확정하지 않는다. 운영자는 빨리 죄송하다는 말을 하고 싶지만, 보상은 데이터와 원인 분석 이후에 결정하는 것이 공정하다. 대신 당일 내 1차 안내, 48시간 내 최종 공지의 타임라인을 약속한다. 반복되는 장애에서는 보상보다 재발 방지 계획이 더 중요하다. 계획이 실현되는 증거를 보여줘야 신뢰가 회복된다.
보안 이슈와 장애의 경계
장애처럼 보이지만, 실제로는 보안 이벤트인 경우가 있다. 스팸 트래픽 급증, 로그인 시도 폭증, 카드 BIN 범위 스캐닝 같은 패턴이다. 속도가 생명인 장애 대응에서, 보안 확인 절차는 속도를 늦춘다. 그래서 미리 룰을 만든다. 특정 임계치 이상의 인증 실패율 상승은 WAF 룰을 단계적으로 강화하고, 의심 구간의 트래픽을 별도 풀로 분리한 뒤 샘플링한다. 중요한 것은 차단 이전에 우회 경로를 확보하는 일이다. 정상 사용자까지 막아버리면 장애가 된다. 보안과 가용성 사이에 완벽한 정답은 없다. 조직마다 위험 감내 수준을 합의해둬야 한다.
과거 새벽 시간대에 리퍼러가 비어 있는 GET 요청이 폭증해 검색 페이지가 사실상 마비된 적이 있었다. 초기에 DDoS로 판단해 IP 차단을 확대했지만, 30분 후 같은 ASN에서 정상 사용자 트래픽도 다수 포함된 것이 확인됐다. 이후에는 레이트 리밋을 사용자 세그먼트 기준으로 바꾸고, CAPTCHA를 단계적으로 삽입하는 우회 전략을 쓰면서 서비스 중단 없이 방어했다. 이 경험 이후 보안 룰 변경도 배포와 동일하게 변경 기록과 롤백 플랜을 요구한다.
모니터링의 함정, 숫자에 속지 않기
지표만 보면 상황을 잘 알 것 같지만, 지표는 관점이다. 평균 응답시간이 개선됐는데 민원은 늘어나는 이상한 경우가 있다. 백분위수의 함정이다. p50이 좋아져도 p95, p99가 나빠지면 장치가 느린 사용자, 네트워크가 취약한 사용자는 더 불편해진다. 장애 대응 시에는 적어도 p95까지 같이 본다. 또 하나, 애그리게이션 간격의 문제다. 1분 단위 지표는 10초 단위 스파이크를 숨긴다. 에러율이 1분 평균 2퍼센트로 보이지만, 실제로는 10초 동안 20퍼센트까지 치솟았다가 내려갈 수 있다. 알림은 짧은 간격과 긴 간격 두 가지를 섞어야 한다.
로그 역시 유용하지만, 과도한 샘플링은 원인을 가린다. 비용 때문에 로그를 10퍼센트만 남기는 환경에서, 특정 에러의 재현 빈도를 과소평가하는 일이 흔하다. 장애 시점만큼은 샘플링을 일시적으로 끄고, 이후 다시 복구하는 기능을 준비해둔다. 비용은 늘지만, 원인 분석 시간을 줄인다.
포스트모템, 비난 없는 회고는 실제로 가능한가
장애가 끝나면 회고가 남는다. 비난 없는 회고를 말로만 외치면 무용지물이다. 핵심은 행동의 변경으로 이어지는가, 그리고 그 변경이 나중에 검증되는가다. 좋은 포스트모템은 다섯 가지를 남긴다. 사고의 타임라인, 직접 원인과 근본 원인, 감지 지연과 의사결정 지연 분석, 재발 방지 액션과 마감일, 알림과 커뮤니케이션 개선점. 특히 의사결정 지연은 사람 문제로 귀결되기 쉬운데, 대개는 정보의 부족이나 과도한 승인 절차가 원인이다. 권한을 넓혀야 할 때와 좁혀야 할 때를 구분해 문서화한다.
실제 조직에서는 마감일이 밀리기 쉽다. 그래서 분기마다 장애 액션 아이템 이행률을 경영 지표로 올려둔다. 개발팀의 KPI가 되면 형식적이 될 수 있다는 우려가 있지만, 아무 지표도 없으면 더 빨리 흐려진다. 밸런스가 필요하다. 액션 수를 줄이고, 효과가 큰 것부터 완료하도록 스코프를 작게 쪼갠다.
재해 복구와 지역 다중화, 비용과 현실의 타협
DR 계획은 문서 속에서만 존재하기 쉽다. 두 지역에 모든 것을 이중화하면 이상적이지만, 비용과 운영 복잡도가 크게 오른다. 현실적 접근은 핵심 데이터와 필수 트랜잭션만 우선순위를 지정해 보호하는 것이다. RTO와 RPO를 비즈니스와 합의한다. 예를 들어 결제는 RPO 0에 가까워야 하지만, 로그 데이터는 RPO 10분도 감내할 수 있다. RTO는 사용자의 인내심과 직접 연결된다. 15분 내 복구가 가능한 구성인지, 실제로 연 1회 이상 훈련하는지에 답할 수 있어야 한다. 훈련 없는 DR은 그림의 떡이다.
클라우드 사업자 내 다중 리전은 설정으로 가능해 보이지만, 네트워크, IAM, 데이터 동기화, 서드파티 종속성 등 숨은 단서가 많다. 특히 라이선스가 리전별로 달리 적용되는 상용 소프트웨어는 장애 시 전환을 가로막는다. 계약과 키 관리까지 포함해서 재점검해야 한다. CDN 역시 모든 POP에서 동일하게 동작하지 않는다. 리전 장애가 발생하면, CDN의 오리진 라우팅 규칙이 의도와 다르게 작동할 수 있다. 테스트는 로컬에서가 아니라 실제 리전 장애를 가정한 캔드 테스트로 진행해야 한다.
팀을 지키는 운영 문화
장애는 사람을 소모시킨다. 새벽 알람, 주말 복구, 포스트모템까지 이어지면 팀은 금방 지친다. 교대제를 만들고, 온콜 수당을 명확히 지급하고, 대체 휴무를 보장한다. 온콜자는 의사결정 권한이 있어야 한다. 권한 없는 온콜은 전화기 지킴이에 불과하다. 장애 대응 매뉴얼은 누구나 읽을 수 있지만, 모두가 같은 실력을 갖추지는 않는다. 정기적인 게임데이로 대응 역량을 끌어올린다. 의도적으로 작은 장애를 만들어 팀이 안전하게 실패해보게 하는 훈련이다. 실전에서는 그 10분의 연습이 차이를 만든다.
또 하나, 사내 공유의 습관. 장애를 겪은 팀만 배운다면, 조직의 학습 속도는 느리다. 주간 공유에서 짧게라도 “이번 주 장애 한 줄 요약, 배운 점 하나”를 소개하면, 같은 실수를 다른 팀이 줄인다. 오피사이트 같이 변화가 잦은 환경에서는 이 공유가 비용을 크게 절약한다.
현장에서 바로 쓸 수 있는 초단기 체크리스트
두꺼운 매뉴얼은 장애 시에 펼쳐지지 않는다. 평소에는 깊이 있는 문서를, 위기에는 손에 잡히는 한 장을. 아래 체크리스트는 실제 운영 중 손에 익힌 순서다. 팀과 스택에 맞게 수정해 붙여두면 좋다.
장애 선언, 채널 오픈, 역할 지정, 타임라인 기록 시작 고객 체감 지표 확인, 상태 페이지 1차 공지 판단 최근 30분 변경사항 확인, 카나리 롤백 또는 플래그 오프 검토 외부 의존성 상태 점검, 임시 폴백 또는 라우팅 전환 트래픽 제어, 읽기 캐시 확장, 핵심 트랜잭션 보호
이 다섯 줄만 지켜도, 대다수의 장애는 확산을 막을 수 있다. 세부 행위는 조직마다 다르지만, 순서와 의사소통은 어디서나 비슷하다.
오피가이드 수준의 실무 팁 몇 가지
오랫동안 현장에서 통했던 자잘하지만 실전적인 팁을 더한다. 완벽한 해법은 아니지만, 작은 차이가 큰 시간을 벌어준다.
첫째, 에러 페이지도 서비스다. 단순한 사과문보다, 현재 상태와 예상 복구 시간을 담은 가벼운 에러 페이지는 고객 이탈을 줄인다. 캐시 가능한 정적 에러 페이지를 CDN에 미리 올려두면, 오리진이 아플 때도 품격을 지킬 수 있다.
둘째, 지갑을 열 타이밍을 정해둔다. 장애 시 즉시 비용을 올려 해결할 수 있는 구간, 예를 들어 메시지 전송 단가가 더 비싸도 성공률 높은 공급자로 스위치하는 판단을, 사전에 CFO와 합의해 둔다. 의사결정이 늦어지지 않는다.
셋째, 메트릭 명명 규칙을 표준화한다. 팀이 바뀌어도 “service.request.error.rate”, “db.connection.utilization”처럼 상식적 네임스페이스를 쓰면, 새 멤버도 빠르게 대시보드를 읽는다.
넷째, 실패 실험을 기록으로 남긴다. “이 방법은 안 먹혔다”는 문장이 다음 장애에서 5분을 절약한다. 희망적 실험을 반복하는 시간은 가장 값비싸다.
다섯째, 고객센터와 기술팀의 핫라인을 만든다. 고객센터는 체감 이슈를 가장 빨리 알고, 기술팀은 원인을 가장 늦게 알 때가 있다. 단 두 줄의 템플릿, “증상, 단말/통신사, 시작 시각”만 정확히 받아도 탐지 속도가 빨라진다.
마무리, 장애를 줄이는 가장 확실한 길
도구와 스택은 바뀐다. 좋은 베스트 프랙티스도 환경을 옮기면 반쪽짜리가 된다. 그러나 장애를 줄이는 원리는 의외로 단순하다. 관측을 신뢰하고, 변경을 작게 하며, 폴백을 준비하고, 기록으로 말하는 것. 오피사이트처럼 변동성이 큰 서비스는 특히 이 원칙의 효과가 크다. 오피가이드 식으로 말하자면, 장애는 없앨 수 없지만, 줄이고 짧게 만들 수 있다. 오늘 하나라도 준비하면, 다음 장애의 첫 10분이 달라진다. 그리고 그 10분이, 고객과 팀을 지킨다.