사전 스트레스 테스트
개념

스트레스 테스트

gabury1

스트레스 테스트는 시스템이 견딜 만하다고 여긴 부하를 일부러 넘겨 걸어 봅니다. 어디서 어떻게 무너지는지를 미리 알아냅니다. 통과가 아니라 고장을 보려는 시험이라 무너뜨리는 데까지 밀어붙입니다.

쉽고 빠른 이해

한계를 넘길 때까지 부하를 올려 가며 시스템이 언제 어떻게 무너지는지 알아내는 시험입니다. 평소 몰리는 최대치의 몇 곱절까지 올려 가며 걸어 보는 것이 그런 시험입니다.

한계를 모르면 손님이 몰리는 날에 그 한계를 처음 만나게 됩니다. 그날은 무엇이 먼저 무너질지도 모르는 채로 손을 써야 합니다. 미리 무너뜨려 보면 한계가 어디이고 무엇부터 손봐야 하는지를 평온할 때 알아 둡니다.

어떻게 하나:

  1. 부하를 조금씩 올리며 응답 시간과 오류를 읽습니다
  2. 더 올려도 못 버티는 지점을 찾습니다. 그때 무엇이 먼저 무너졌는지 적습니다
  3. 부하를 걷고 저절로 돌아오는지 봅니다

무너뜨리는 시험이라 쓰고 있는 서비스에 걸면 손님이 피해를 봅니다. 닮은 환경을 따로 갖추는 비용이 대가입니다.

상세

차가 늘어도 어느 정도까지는 도로가 제 속도로 흐릅니다. 그 선을 넘기면 속도가 떨어지기 시작해 결국 멈춰 섭니다. 멈춰 선 뒤에는 뒤에서 들어오는 차를 막아도 줄이 한참 동안 풀리지 않습니다.

스트레스 테스트는 기대한 범위를 넘는 부하를 일부러 걸어 시스템이 무너지는 지점과 무너지는 모습을 알아내는 시험입니다. 평소 가장 붐비는 때의 요청 수를 아는 서비스라면, 그 몇 곱절까지 올려 가며 거는 것이 이 시험입니다. 무너진 뒤에도 요청은 계속 들어옵니다. 그래서 무너지는 지점만이 아니라 무너진 다음에 벌어지는 일까지를 봅니다.

부하 테스트와 거는 방법은 같습니다. 다른 것은 목적입니다. 부하 테스트는 예상 범위 안의 부하를 걸어 그 범위를 감당하는지 확인합니다. 스트레스 테스트는 그 범위 밖으로 밀어 범위가 어디까지인지를 찾습니다.

두 시험이 미는 데까지를 하나의 부하 축 위에 놓으면 이렇게 나뉩니다. 응답이 아직 기다릴 만한 상한을 한계 용량이라고 하고, 무너지는 구간은 그보다 뒤에 있습니다.

block-beta
columns 4
  a["평소 부하"] b["예상 최대"] c["한계 용량"] d["무너지는 구간"]
  e["부하 테스트"]:2 f["스트레스 테스트"]:2

부하 테스트는 예상 최대까지만 걸고 멈춥니다. 스트레스 테스트는 그 너머로 밀어 한계 용량이 어디이고 무너지는 구간이 어디인지를 찾습니다.

한계를 모른 채 두면 그 한계를 실제 손님이 몰리는 날에 처음 만나게 됩니다. 그날은 어디까지 버티는지도, 무엇이 먼저 무너질지도 모르는 채로 대응해야 합니다. 미리 무너뜨려 보는 것은 그 첫 만남을 아무도 다치지 않는 때로 옮기는 일입니다.

시험이 알아내는 세 가지

첫째는 한계 용량입니다. 응답이 기다릴 만한 수준으로 돌아오는 부하가 어디까지인지를 값으로 잡습니다. 무너지는 지점이 그대로 쓸 수 있는 한계는 아닙니다. 앞으로 자원을 얼마나 늘릴지 정하는 용량 계획에는 무너진 부하가 아니라 이 값을 넣습니다.

둘째는 무너지는 방식입니다. 한계 용량을 넘겼을 때 무엇이 먼저 주저앉는지를 봅니다. 데이터베이스로 가는 연결이 먼저 동나는지, 메모리가 먼저 차는지에 따라 손볼 곳이 달라집니다.

셋째는 되돌아오는가입니다. 부하를 걷은 뒤까지가 시험 범위에 들어간다는 뜻입니다. 한 번 넘어진 뒤 제힘으로 못 일어나는 시스템은 멈춰 있는 시간이 길어집니다.

부하를 올리는 방법

부하는 한 번에 확 올리지 않고 한 단계씩 올립니다. 한 번에 올리면 무너진 것은 보이는데 어느 부하에서 무너졌는지는 모릅니다. 갑자기 확 올려 그 급변을 견디는지 보는 것은 스파이크 테스트가 따로 맡습니다.

한 단계를 올린 다음에는 잠시 그 부하를 유지한 채 응답 시간과 오류가 어떻게 변하는지 읽습니다. 올리자마자 다음 단계로 가면 값이 아직 출렁이는 동안 읽게 되어 한계를 잘못 잡습니다.

flowchart TD
    A["부하를 한 단계 올린다"] --> B["잠시 유지하며 응답 시간과 오류를 읽는다"]
    B --> C{"아직 버티나"}
    C -->|"버틴다"| A
    C -->|"무너졌다"| D["무너진 부하와 무너진 모습을 적는다"]
    D --> E["부하를 걷고 돌아오는지 본다"]

무너진 다음에도 단계가 하나 더 남습니다. 부하를 걷고 시스템이 돌아오는지 보는 단계입니다. 무너뜨린 데서 멈추면 이 시스템이 저절로 복구되는지 아닌지를 모른 채 끝납니다.

한계를 넘기면 나오는 두 가지 모습

한계를 넘긴 시스템이 보이는 모습은 크게 둘로 갈립니다. 어느 쪽인지는 걸어 보기 전에는 알 수 없습니다. 이 갈림을 미리 보려고 이 시험을 돕니다.

하나는 서서히 나빠지는 모습입니다. 부하가 늘수록 응답 시간이 같이 늘어납니다. 일부 요청은 실패합니다.

한계를 조금 넘겨도 서비스가 이어지므로, 그 사이에 자원을 늘리거나 부하를 줄일 틈이 있습니다. 일부 기능을 꺼서라도 나머지를 살리는 우아한 저하가 이 모습을 노리고 넣는 장치입니다.

다른 하나는 어느 지점을 넘는 순간 통째로 주저앉는 모습입니다. 이때는 거는 요청이 늘어도 실제로 끝까지 처리해 내는 양(처리량)은 되레 떨어집니다.

떨어지는 까닭은 셋입니다. 대기 줄이 쌓여 기다리는 요청이 늘어납니다. 정해둔 시간 안에 답이 안 와서 끊는 타임아웃이 걸립니다. 끊긴 요청은 다시 오므로 부하가 스스로 더 커집니다.

flowchart TD
    A["부하가 한계를 넘는다"] --> B["대기 줄이 쌓인다"]
    B --> C["타임아웃이 걸려 요청을 끊는다"]
    C --> D["끊긴 요청을 다시 보낸다"]
    D --> A
    B --> E["처리량이 되레 떨어진다"]

이 셋은 따로 놀지 않고 고리로 이어집니다. 끊긴 요청이 다시 부하가 되어 처음으로 돌아가기 때문입니다. 부하를 걷기 전에는 고리가 저절로 끊기지 않습니다.

한 부품이 주저앉자 그 뒤로 줄줄이 넘어가는 연쇄 장애가 이렇게 시작됩니다.

부하를 걷은 뒤의 복구

부하를 걷어도 시스템이 곧바로 돌아오지 않는 경우가 있습니다. 무너지는 동안 밀린 일이 남아 있기 때문입니다. 대기 줄에 쌓인 요청, 끊겼다가 한꺼번에 몰려오는 재시도, 비워진 캐시를 채우려고 원본으로 쏟아지는 조회가 그런 일감입니다.

그래서 복구까지가 시험 범위입니다. 저절로 돌아오는지, 사람이 재시작해야 돌아오는지, 돌아오는 데 얼마나 걸리는지를 적습니다. 이 값이 장애가 났을 때 서비스가 멈춰 있는 시간을 가늠하는 근거가 됩니다.

무너지는 모습이 둘로 갈려도 그 뒤의 길은 하나로 모입니다. 밀린 일을 처리하는 단계를 지나야 정상으로 돌아오고, 못 지나면 사람이 재시작합니다.

stateDiagram-v2
    state "정상" as N
    state "서서히 나빠짐" as S
    state "통째로 주저앉음" as C
    state "밀린 일 처리" as R
    state "사람이 재시작" as M
    N --> S: 한계를 넘긴다
    N --> C: 한계를 넘긴다
    S --> R: 부하를 걷는다
    C --> R: 부하를 걷는다
    R --> N: 저절로 돌아온다
    R --> M: 저절로 안 돌아온다
    M --> N

시험을 거는 환경

쓰고 있는 서비스에 걸면 시험이 곧 장애입니다. 그래서 대개 닮게 꾸민 환경을 따로 두고 거기에 겁니다.

다만 닮은 정도만큼만 믿을 수 있습니다. 데이터 양이 적거나, 장비가 작거나, 옆에서 같이 도는 이웃 서비스가 없으면 무너지는 지점이 달라집니다. 시험 환경을 어디까지 닮게 만들지와 거기에 드는 비용 사이에서 고르는 것이 이 시험의 대가입니다.

이웃한 시험과 가르는 선

부하를 걸어 성능을 보는 시험은 여럿입니다. 거는 방법이 비슷해서 이름이 섞여 쓰입니다. 가르는 기준은 무엇을 알아내려는가입니다.

시험 얼마나 거나 무엇을 알아내나
부하 테스트 예상 범위 안 그 범위를 감당하나
스트레스 테스트 예상 범위 밖 어디서 어떻게 무너지나
스파이크 테스트 짧게 확 올렸다 내림 급격한 변화를 견디나
소크 테스트 보통 부하로 오래 시간이 갈수록 새는 것이 있나

표에서 보듯 스트레스 테스트만 범위 밖으로 나갑니다. 나머지 셋은 무너뜨리는 것이 목적이 아니라 정해둔 조건에서 버티는지를 확인합니다.

관련 항목

스트레스 테스트와 목적이 갈리는 성능 시험

부하 테스트 · 스파이크 테스트 · 소크 테스트 · 성능 테스트 · 벤치마크 · 스모크 테스트 · 카오스 엔지니어링 · 장애 주입

무너지는 지점을 읽을 때 보는 지표

응답 시간 · 처리량 · 오류율 · 초당 요청 수 · 지연 · 백분위수 · 사용률 · 가용성

부하를 만들어 거는 도구와 그 설정값

k6 · Locust · JMeter · 부하 생성기 · 가상 사용자 · 램프업 · 임계값

한계를 넘겼을 때 먼저 주저앉는 고장

병목 · 커넥션 풀 고갈 · 메모리 누수 · 연쇄 장애 · 썬더링 허드 · 큐 대기 · 백프레셔

무너지지 않게 버티려고 두는 장치

서킷 브레이커 · 우아한 저하 · 스로틀링 · 재시도 · 타임아웃 · 오토스케일링 · 로드 밸런서 · 수평 확장

시험 결과를 받아 쓰는 운영 작업

용량 계획 · 모니터링 · 경보 · 대시보드 · SLO · 성능 기준선 · 성능 회귀 · QA와 테스트

다른 이름: stress testing · stress test · 스트레스 시험