(5/6) 홈페이지 스트레스 테스트 — 복원력과 카오스 엔지니어링
Summary
지금까지는 “부하를 얼마나 견디나”를 쟀어요. 그런데 실전 장애는 부하 때문만이 아니에요. DB 가 잠깐 응답을 멈추거나, 결제 API 가 느려지거나, 서버 한 대가 갑자기 빠지거나 — 이런 부분 고장이 훨씬 흔합니다. 이때 홈페이지가 통째로 무너지느냐, 아니면 고장 난 부분만 우아하게 잘라내고 나머지는 계속 도느냐. 그 차이를 만드는 게 복원력(resilience) 이에요.
이번 편은 부하 대신 장애를 일부러 주입해서 복원력을 시험합니다. 이게 카오스 엔지니어링이에요. “고장은 반드시 난다”를 전제로, 평상시에 안전하게 고장을 일으켜보고 시스템이 잘 버티는지 확인하는 거예요. 함께 갖춰야 할 방어 패턴(타임아웃·재시도·서킷브레이커·폴백)도 같이 정리합니다.
💡 이 글에서 다루는 것
- 카오스 엔지니어링 — 왜 일부러 고장을 내나
- 복원력을 만드는 네 패턴 — 타임아웃·재시도·서킷브레이커·폴백
- 의존성 장애 주입 — DB·외부 API 가 느려지거나 죽으면
- 인프라 장애 주입 — 서버 다운·네트워크 지연
- 안전하게 실험하는 원칙 (폭발 반경 제한)
1. 카오스 엔지니어링 — 왜 일부러 고장을
상식과 반대로 들려요. 멀쩡한 시스템에 일부러 고장을 낸다니. 하지만 논리는 단단합니다. 고장은 언젠가 반드시 납니다. 서버는 죽고, 네트워크는 끊기고, 외부 API 는 느려져요. 그렇다면 선택지는 둘뿐이에요. 새벽 3시에 예고 없이 겪거나, 아니면 낮에 내가 통제하는 상황에서 미리 겪어보거나.
카오스 엔지니어링은 후자를 택하는 거예요. 넷플릭스가 “카오스 몽키”라는 도구로 운영 서버를 무작위로 죽이면서 시작한 방식으로, 핵심 사고방식은 이렇습니다.
- 시스템이 정상일 때의 상태를 가설로 정의한다. (“서버 한 대가 죽어도 에러율은 1% 미만이어야 한다.”)
- 현실의 장애를 일부러 주입한다. (서버 한 대를 죽인다.)
- 가설이 맞았는지 확인한다. 틀렸다면 그게 오픈 전에 고칠 약점이에요.
이건 부하 테스트와 다른 종류의 시험이에요. 부하 테스트가 “많이 오면 버티나”라면, 카오스는 “일부가 고장 나도 버티나”를 봅니다. 둘 다 필요해요.
⚠️ 카오스 엔지니어링은 “무작정 다 부수기”가 아니에요. 가설을 세우고 → 작게 주입하고 → 결과를 확인하는 과학 실험에 가깝습니다. 그냥 서버를 랜덤하게 죽이는 건 실험이 아니라 사고예요.
2. 복원력을 만드는 네 패턴
장애를 주입하기 전에, 애초에 홈페이지가 장애를 견디려면 어떤 방어 장치가 있어야 하는지부터 알아야 해요. 카오스 테스트는 결국 이 방어 장치들이 실제로 작동하는지 확인하는 활동이거든요. 핵심 네 가지를 정리합니다.
| 패턴 | 하는 일 | 없으면 생기는 일 |
|---|---|---|
| 타임아웃 | 정해진 시간 안에 응답 없으면 포기 |
느린 의존성 하나에 전체가 매달려 멈춤 |
| 재시도 | 일시적 실패를 잠깐 뒤 다시 시도 |
순간적 오류에도 사용자에게 에러 |
| 서킷브레이커 | 계속 실패하는 곳은 아예 호출 차단 |
죽은 서비스를 계속 두드려 악화 |
| 폴백 | 실패 시 대체 응답 제공 |
일부 실패가 전체 화면 붕괴로 |
이 넷은 함께 작동해요. 예를 들어 상품 페이지에서 추천 목록을 불러올 때: 타임아웃 300ms 를 걸고, 실패하면 두어 번 재시도하고, 계속 실패하면 서킷브레이커가 호출을 끊고, 그동안엔 “추천 없음” 대신 인기 상품을 보여주는 폴백을 냅니다. 이러면 추천 서비스가 완전히 죽어도 상품 페이지는 멀쩡하게 떠요.
🚨 특히 타임아웃 없는 호출이 가장 위험합니다. 외부 API 하나가 응답 없이 매달리면, 그 요청을 처리하던 스레드·커넥션이 계속 잡혀 있다가 결국 전부 고갈돼요. 한 곳의 느려짐이 전체 다운으로 번지는 연쇄 장애(cascading failure)의 시작이 대부분 여기예요. 모든 외부 호출에는 타임아웃을 거세요.
3. 의존성 장애 주입
가장 자주 터지는 실전 장애는 서버 자체가 아니라 의존하는 것이 말썽을 부리는 경우예요. DB 가 느려지거나, 외부 결제·인증·배송 API 가 응답을 안 하는 상황. 이걸 일부러 만들어봅니다.
주입해볼 시나리오를 정리하면 이래요.
- 의존성 지연 — DB나 외부 API 응답에 3초 지연을 주입해요. 앞서 건 타임아웃이 제대로 작동해 요청을 끊는지 확인합니다.
- 의존성 다운 — 외부 API 를 아예 응답 없음이나 에러로 만들어요. 서킷브레이커가 열리고 폴백이 나오는지 확인합니다.
- 의존성 에러율 증가 — 요청의 30%를 실패로 돌려요. 재시도가 이걸 흡수하는지, 아니면 재시도 폭풍으로 오히려 악화되는지 확인합니다.
주입 방법은 여러 가지예요. 개발/스테이징이라면 코드에 장애 주입 토글을 심어두는 게 가장 간단합니다. 특정 환경 변수가 켜지면 일부러 지연·에러를 넣는 식이에요.
import os, time, random
def call_payment_api(order):
# 카오스 실험용 장애 주입 (스테이징에서만 켬)
if os.getenv("CHAOS_PAYMENT_DELAY"):
time.sleep(3) # 3초 지연 주입
if os.getenv("CHAOS_PAYMENT_FAIL") and random.random() < 0.3:
raise ConnectionError("주입된 장애") # 30% 확률 실패
return real_payment_call(order)
이 토글을 켠 채로 2편의 k6 부하를 함께 걸면, “결제 API 가 3초씩 느려진 상태에서 부하가 들어오면 홈페이지 전체가 어떻게 되나”를 볼 수 있어요. 타임아웃과 폴백이 잘 작동한다면, 결제만 잠깐 막히고 나머지 페이지는 멀쩡해야 합니다. 그렇지 않고 전체 응답 시간이 같이 3초로 밀린다면, 격리가 안 된 거예요.
프록시 계층에서 주입하는 방법(Toxiproxy 같은 도구)도 있어요. 코드를 안 건드리고 네트워크 중간에서 지연·끊김을 넣을 수 있어서, 여러 의존성을 한꺼번에 실험할 때 편합니다.
4. 인프라 장애 주입
의존성 다음은 인프라 자체예요. 서버가 죽거나, 네트워크가 지연되거나, 디스크가 차는 상황. 클라우드에서 여러 대로 운영한다면 이런 실험이 꼭 필요해요.
- 서버 한 대 종료 — 인스턴스 하나를 죽입니다. 로드밸런서가 죽은 서버를 빼고 나머지로 트래픽을 보내는지, 오토스케일이 새 서버를 띄우는지 확인. 이때 사용자에게 에러가 얼마나 새어 나가는지가 핵심이에요.
- 가용 영역(AZ) 장애 — 한 데이터센터 구역이 통째로 빠지는 상황. 여러 구역에 분산해뒀다면 나머지로 버텨야 합니다.
- 네트워크 지연·단절 — 서버 간 통신에 지연을 주입. 마이크로서비스라면 서비스 사이 지연이 어떻게 번지는지 봅니다.
- CPU·메모리·디스크 포화 — 서버 자원을 인위적으로 채워서, 자원이 부족할 때 우아하게 성능이 떨어지는지 아니면 급사하는지 확인합니다.
리눅스에는 이런 장애를 주입하는 도구가 있어요. 예를 들어 스트레스 도구로 CPU 를 인위적으로 채웁니다.
# CPU 코어 4개를 60초 동안 100%로 채우기
stress-ng --cpu 4 --timeout 60s
이걸 한 서버에 걸어두고 부하를 보내면, “CPU 가 포화된 서버가 로드밸런서에서 제대로 빠지나, 아니면 느린 채로 트래픽을 계속 받나”를 볼 수 있어요. 쿠버네티스 환경이라면 LitmusChaos·Chaos Mesh 같은 전용 도구로 Pod 종료·네트워크 지연을 선언적으로 주입할 수도 있습니다.
💡 인프라 장애 실험의 첫 목표는 “죽어도 되는 걸 죽였을 때, 사용자가 눈치채지 못하는가”예요. 서버 한 대를 죽였는데 사용자 에러가 0 이면 훌륭한 복원력입니다. 에러가 왕창 샌다면, 로드밸런서 헬스체크나 재시도 설정을 고칠 지점이에요.
5. 안전하게 실험하기
카오스 실험은 잘못하면 진짜 장애가 돼요. 안전하게 하는 원칙을 정리합니다.
- 폭발 반경(blast radius)을 작게 — 처음엔 트래픽의 1%, 서버 한 대처럼 아주 좁은 범위로 시작해요. 괜찮으면 조금씩 넓힙니다.
- 중단 스위치를 준비 — 실험을 즉시 멈추고 정상으로 되돌리는 버튼을 먼저 만들어두세요. 이게 없으면 실험을 시작하면 안 돼요.
- 스테이징에서 먼저 — 운영에서 하기 전에 반드시 스테이징에서 검증합니다. 운영 카오스는 성숙한 팀이 충분한 관측·자동복구를 갖춘 뒤의 이야기예요.
- 팀에 공지하고, 지켜보며 — 실험 중엔 지표를 실시간으로 봅니다. 가설과 다르게 흘러가면 즉시 중단.
✅ 신규 오픈 홈페이지라면 운영 카오스까지 갈 필요 없어요. 스테이징에서 “의존성 하나 죽이기 + 서버 한 대 죽이기” 두 가지만 해봐도, 타임아웃·폴백·로드밸런서가 실제로 작동하는지 확인할 수 있습니다. 이것만 해도 실전 사고의 상당수를 미리 막아요.
6. 정리
- 카오스 엔지니어링 = 가설 세우고 → 장애 주입하고 → 확인하는 과학 실험
- 복원력 네 패턴 — 타임아웃·재시도·서킷브레이커·폴백, 특히 타임아웃 필수
- 의존성 장애(DB·외부 API 지연/다운)를 주입해 격리와 폴백을 확인
- 인프라 장애(서버 다운·자원 포화)를 주입해 로드밸런서·오토스케일을 확인
- 폭발 반경을 좁게, 중단 스위치 먼저, 스테이징에서 먼저
이제 홈페이지가 부하도 견디고 장애도 버티는지 확인했어요. 마지막으로 남은 건 악의를 가진 부하 입니다. 정상 사용자가 아니라 공격자가 홈페이지를 무너뜨리려 할 때 — 무차별 요청, 비정상 트래픽, 취약점 공략 — 를 견디는지. 다음 편에서 보안·가용성 스트레스와 함께, 6부작 전체를 아우르는 종합 체크리스트로 마무리할게요.
일단 오늘은 여기까지….. 다음 글에서는 보안·가용성 스트레스와 종합 체크리스트를 정리해볼게요.
← 이전 글: (4/6) 홈페이지 스트레스 테스트 — 백엔드·DB 병목 찾기 | 다음 글 →: (6/6) 홈페이지 스트레스 테스트 — 보안·가용성과 종합 체크리스트