사전 가상 사용자
개념

가상 사용자

gabury1

부하 테스트 도구가 사람 한 명 몫으로 만들어 내는 가짜 사용자입니다. 미리 적어 둔 시나리오를 처음부터 끝까지 되풀이해 실행합니다. 여럿을 동시에 띄워서 서버가 사람 여럿을 상대하는 상황을 흉내 냅니다.

상세

새로 연 가게가 손님을 몇 명까지 받을 수 있는지 알고 싶을 때, 손님을 진짜로 부르는 대신 직원들이 손님인 척 줄을 서 보고 주문해 봅니다. 가상 사용자는 적어 준 시나리오만 밟기 때문에, 진짜 사용자가 하는 예상 밖의 행동은 하지 않습니다.

가상 사용자 하나는 정해진 시나리오 하나를 대상 서버에 대고 실행합니다. 다른 가상 사용자와 상관없이 혼자 돕니다. 여럿을 동시에 띄우면 서버 쪽에서 보는 동시 접속이 그만큼 늘어납니다.

시나리오를 처음부터 끝까지 한 번 실행한 것을 반복이라고 부릅니다. 가상 사용자는 테스트가 끝날 때까지 이 반복을 되풀이합니다.

sequenceDiagram
    participant V as 가상 사용자
    participant S as 대상 서버
    loop 반복 하나
        V->>S: 시나리오 첫 단계 요청
        S-->>V: 응답
        V->>S: 시나리오 다음 단계 요청
        S-->>V: 응답
    end
    Note over V: 시나리오를 다 마치면 다음 반복을 시작합니다

어떤 도구는 도중에 인원을 줄여도 이미 도는 가상 사용자를 중간에 끊지 않습니다. 시나리오를 끝까지 마치는 것이 그 가상 사용자가 사라지는 유일한 길입니다.

가상 사용자 하나에는 실행 단위 하나가 배정됩니다. 무엇을 배정하는지는 도구가 정합니다. 운영체제 스레드 하나를 통째로 주는 도구도 있고, 스레드에 비해 값이 싼 코루틴 하나를 주는 도구도 있습니다. 그래서 가상 사용자 수와 실제로 뜬 스레드 수는 같지 않을 수 있습니다.

목표 인원까지 한꺼번에 올리지는 않습니다. 시간을 두고 조금씩 늘리고, 그 시간을 램프업이라고 부릅니다. 램프업이 짧으면 테스트를 시작하는 순간에 부하가 한꺼번에 몰립니다. 반대로 너무 길면 먼저 시작한 가상 사용자가 끝나 버린 뒤에 마지막 인원이 뜹니다.

가상 사용자는 공짜가 아닙니다. 부하를 만드는 쪽 컴퓨터의 CPU(Central Processing Unit, 중앙처리장치)와 메모리를 씁니다. 인원을 올리면 그 자원 사용도 따라 올라갑니다. 부하를 만드는 쪽이 먼저 포화되면 측정값이 대상 서버가 아니라 부하 생성기의 한계를 보여 줄 수 있습니다.

배경

부하 테스트는 서버에 요청을 몰아넣고 그때 무엇이 무너지는지를 봅니다. 요청을 몰아넣으려면 동시에 도는 실행 단위가 여럿 있어야 합니다. 실행 단위 하나가 요청 하나를 보내는 동안 다른 실행 단위가 자기 요청을 보내야 동시 접속이 만들어집니다.

같은 요청을 복사해서 뿌리는 것만으로는 모자랐습니다. 사용자마다 페이지 내용이 다른 사이트에서는 그렇게 만든 부하가 실제로 걸리는 부하와 다릅니다. 기존 도구들이 이 대목에 잘 갖춰져 있지 않았다는 불만이 새 도구를 만든 이유로 공식 문서에 적혀 있습니다.

그래서 필요했던 것은 요청 하나가 아니라 시나리오 한 벌을 처음부터 끝까지 밟는 단위였습니다. 그 단위를 사람 수로 세기 때문에 가상 사용자라고 부릅니다. 줄여 쓸 때는 VU(Virtual User)라고 적습니다.

부르는 이름은 도구마다 다릅니다. 어떤 도구는 스레드라고 부르고, 어떤 도구는 그냥 사용자라고 부릅니다. 가리키는 것은 같습니다. 시나리오를 되풀이 실행하는 실행 단위 하나입니다.

예시

Apache JMeter 스레드 그룹

스레드 그룹 요소가 테스트 계획의 시작점입니다. 여기서 스레드 수, 램프업 기간, 반복 횟수를 정합니다. 스레드 하나는 테스트 계획 전체를 다른 스레드와 완전히 무관하게 실행합니다.

스레드 10개에 램프업 기간 100초를 주면 10개가 다 뜨는 데 100초가 걸립니다. 앞 스레드가 시작한 뒤 10초(100/10)마다 다음 스레드가 시작합니다. 스레드 30개에 램프업 120초면 스레드마다 4초씩 밀립니다.

Azure Load Testing 공식 문서는 JMeter 가 가상 사용자를 스레드라고 부르고, Locust 는 그냥 사용자라고 부른다고 적어 둡니다.

Grafana k6 constant-vus

JavaScript
export const options = {
  scenarios: {
    closed_model: {
      executor: 'constant-vus',
      vus: 1,
      duration: '1m',
    },
  },
};

가상 사용자 한 명을 1분 동안 돌립니다. 시나리오 안의 요청 하나가 약 6초 걸리므로 반복 하나가 6초입니다. 그래서 1분 동안 반복 10개가 끝납니다. 실행 결과는 이렇게 찍힙니다.

running (1m01.5s), 0/1 VUs, 10 complete and 0 interrupted iterations
closed_model ✓ [======================================] 1 VUs 1m0s

인원과 반복 수가 따로 찍힙니다. 한 명이 열 번을 돈 것이지 열 명이 뜬 것이 아닙니다.

PostgreSQL pgbench

웹 밖에서도 같은 자리가 있습니다. pgbench 는 SQL(Structured Query Language) 명령 묶음을 되풀이 실행하고 평균 처리율을 계산하는 벤치마크 프로그램입니다. -c clients 옵션이 흉내 낼 인원을 정하고, 공식 문서는 그 값을 "동시 데이터베이스 세션의 수"라고 적습니다. 기본값은 1입니다.

number of clients: 10
number of threads: 1

전형적인 출력에서 클라이언트 수와 스레드 수가 다른 줄에 따로 찍힙니다. 클라이언트 10개를 스레드 1개가 굴리고 있습니다. 가상 사용자 하나가 곧 운영체제 스레드 하나인 것은 아니라는 사실이 여기서 값으로 드러납니다.

경계

가상 사용자를 200명으로 올리면 초당 요청도 200번이 되나. 아닙니다.

Azure Load Testing 공식 문서가 둘을 잇는 식을 적어 둡니다. 가상 사용자 = 초당 요청 수 × 지연(초) 입니다. 초당 요청 수는 RPS(Requests Per Second)라고도 적습니다. 이 식대로면 지연이 20밀리초일 때 초당 10만 번을 흉내 내는 데 가상 사용자 2,000명이 듭니다. 인원이 그대로여도 지연이 달라지면 초당 요청 수가 달라진다는 뜻이기도 합니다.

왜 그런지는 가상 사용자를 언제 다시 출발시키느냐에 달려 있습니다. 닫힌 모델(closed model)에서는 앞 반복이 끝나야 다음 반복이 시작합니다. 그래서 반복 하나에 걸리는 시간이 새 반복의 출발 속도를 그대로 정합니다. 대상 서버의 응답 시간이 늘어나면 반복이 길어지고, 새 반복이 출발하는 속도가 떨어집니다. k6 공식 문서는 시험 문헌에서 이 문제를 coordinated omission 이라고 부른다고 적습니다.

열린 모델(open model)은 이 결합을 끊습니다. 가상 사용자가 앞 반복이 끝났는지와 상관없이 도착합니다. 대상 서버의 응답 시간이 테스트가 거는 부하에 영향을 주지 못하게 됩니다.

그래서 "몇 명을 띄웠나"와 "초당 몇 번을 보냈나"는 서로 다른 눈금입니다. 인원만 보고 부하의 크기를 말할 수 없고, 두 눈금을 같이 봐야 합니다.

관련 항목

가상 사용자가 쓰이는 테스트 갈래

부하 테스트 · 성능 테스트 · 스트레스 테스트 · 스모크 테스트 · 벤치마크 · QA와 테스트(Quality Assurance, 품질보증)

가상 사용자 실행에 관여하는 도구

시나리오 · 테스트 스크립트 · 부하 생성기 · SQL · 데이터베이스

가상 사용자를 가리키는 다른 이름

스레드 · 클라이언트 · 세션

가상 사용자에 배정되는 실행 단위와 자원

코루틴 · 그린렛 · 스레드 풀 · 커넥션 풀 · 문맥 교환 · 동시성 · 태스크 · 운영체제 · CPU · 메모리

인원과 부하를 재는 지표

램프업 · 도착률 · 동시 접속 · 처리량 · 초당 요청 수 · 지연 · 응답 시간 · 백분위수 · 오류율 · 메트릭 · 서비스 수준 목표 · 성능

측정값을 흐리는 요인

coordinated omission · 포화 · 병목 · think time

다른 이름: virtual user · VU · virtual users