ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [nGrinder] 사용법 및 테스트
    서버 2016. 5. 21. 12:08

    앞서 nGrinder가 어떻게 동작하고, 자주 사용되는 용어를 확인했다면, 지금부터는 실제로 테스트를 하면서 테스트 확인 페이지에 나오는 용어 및 그래프들에 대한 설명을 하겠습니다.

    로컬환경



    VirtualBoxVirtualBox CPUVirtualBox Memorycontainer nameGuest OSdocker CPUdocker MEMORYDocker
    coreos-controller2core2gbcontroller




    coreos stable(835.11.0) 

    2core2gb




    1.8.3



    coreos-agent



    2core



    4gb

    agent_1c1g1core1gb
    agent_1c2g1core2gb
    agent_1c4g1core4gb
    agent_2c2g2core2gb
    agent_2c4g2core4gb

    위와 같은 환경을 설정하기 위해, vm을 총 4개가 아닌 2개만 설정하고 docker에서 컨테이너마다 각 다른 cpu와 memory를 할당하여 테스트를 진행했습니다.

    사전 설정


    vm을 2개만 사용해 docker 컨테이너마다 자원을 다르게 설정해줘야 합니다.

    먼저 nGrinder의 controller와 agent를 설치합니다. (nGrinder란#nGrinder설치-docker 참고)

    controller는 설명대로 바로 설치합니다. agent는 cpu와 memory를 아래와 같이 설정하여 줍니다.

    $  docker run -d -e 'CONTROLLER_ADDR=ip주소:8080' --memory="1g" --memory-swap -1 --cpu-period=50000 --cpu-quota=25000 --name agent_minimum ngrinder/agent:3.3

    --memory  : 해당 컨테이너에 물리적으로 메모리를 얼마나 할당할 지 설정하여 줍니다. 할당받은 메모리를 전부 사용했을 시, host의 메모리를 빌려서 사용합니다.

    --memory-swap  : 컨테이너에게 얼만큼 메모리를 빌려줄 지 결정합니다. 만약 --memory="300m" --memory-swap="200m"일 경우, 해당 컨테이너에서 사용할 수 있는 메모리의 양은 500m입니다. 여기서는 정확하게 1gb/2gb/4gb만 사용하기 위해 -1로 메모리를 고정합니다.

    --cpu-period, --cpu-quota  :  cpu-priod는 cpu-quota와 함께 사용합니다. cpu-priod의 기본 값은 100000(100ms)로, cpu-quota를 이용해서 100ms 동안 어느정도의 cpu 할당할 것 인지를 설정할 수 있습니다. 만약 cpu-quota가 25000이라면, 1/4만큼의 cpu자원을 사용할 수 있습니다. 여기서 agent vm을 2core로 설정하였기 때문에 1/2만큼의 cpu자원을 사용하도록 하기 위해 --cpu-period는 50000, --cpu-quota는 25000을 정했습니다.


    이러한 방식으로 agent를 각기 다른 자원을 할당해 생성합니다.

    nGrinder Architechure


    세팅한 nGrinder는 다음과 같은 구조로 controller와 agent들이 통신하고 agent들은 test 서버에 부하를 가합니다.


    포트 별 통신 내용은 nGrinder란#포트에 정리가 되어 있습니다.


    테스트 방법 및 화면 설명


     



    URL을 입력하고 버튼을 누르면 보이는 페이지 입니다. 테스트명, 태그, 설명은 저장할 때 해당 테스트를 설명하는 항목입니다.

    에이전트는 controller와 연결되어 있는 에이전트의 수 만큼 사용할 수 있습니다. + 버튼을 누르면  이와 같이 설정을 할 수 있습니다.

    스크립트는 사용자가 해당 주소로 부하를 걸 스크립트를 보여줍니다.

    RHEAD는 선택된 스크립트의 내용을 보여주는 페이지로 이동합니다.

    테스트 대상 서버는 테스트를할 서버의 리스트를 보여줍니다. 추가버튼을 눌러 테스트를 받을 서버를 늘릴 수 있습니다.

    테스트 기간은 해당 테스트를 얼마 만큼 실행할 지 설정하는 항목입니다. 사용자는 테스트 기간과 실행 횟수 둘 중 하나만 골라 실행할 수 있습니다.

    실행 횟수는 사용자가 설정한 쓰레드당 몇 번의 테스트를 실행할 것인지 지정합니다.  사용자는 테스트 기간과 실행 횟수 둘 중 하나만 골라 실행할 수 있습니다.

    Ramp_Up은 점차 부하를 가할 수 있는 기능입니다. 점차 부하를 가할 때, vuser의 수를 늘리는 것이 아닌, process나 thread를 늘립니다. 

    초기 개수는 처음 시작할 때, vuser의 수를 설정합니다.

    초기 대기시간은 테스트를 언제부터 실행시킬 지 설정합니다.

    증가 단위는 해당 쓰레드/프로세스를 몇 개씩 증가시킬지 설정합니다.

    Ramp-Up 주기는 설정한 것들의 상승 시간을 설정합니다.

    샘플링 주기는 그래프 x축에 보여질 '초'를 나타냅니다.

    샘플링 무시 횟수는 적혀진 숫자 * 샘플링 주기만큼 데이터가 수집되지 않습니다.

    파일 안전 전송은 에이전트에 스크립트를 항상 오류없이 전달하고 싶을 때 체크합니다.

    파라미터는 테스트 실행 중에 참조할 수 있는 파라미터를 부여할 수 있습니다.



    MTT: 평균 테스트 타임 vuser를 늘리면 MTT또한 비례하게 늘어납니다. 

    MTFB: 평균 첫 번째 바이트 도달 시간이며 이것을 Response Time으로 볼 수도 있습니다.


    상세 보고서 버튼을 클릭 시, 각 항목에 대해 그래프로 확인할 수 있습니다.


    상단 성능 테스트 버튼을 누르면 그동안 테스트했던 결과를 확인할 수 있고, 생성할 수도 있습니다.


    웹페이지를 테스트했던 스크립트들을 확인할 수 있고, 생성, 업로드할 수도 있습니다.

    시스템 설정


    시스템 설정에서 제한이 있는 부분들을 해결할 수 있습니다. 예로 vuser는 에이전트당 3000으로 고정되어 있는 것을 50000으로 풀겠습니다.


    controller.max_vuser_per_agent의 주석처리를 푼 다음, 3000을 50000으로 변경하여 저장합니다.

    테스트모드로 들어가면 아래와 같이 변경된 것을 확인할 수 있습니다.


    이처럼 제한이 된 부분들을 사용자가 원하는 대로 풀 수도 있고, 반대로 제한을 줄 수도 있습니다.

    사용자 관리


    위 사진처럼 사용자 관리를 들어가면 기본으로 설정되어 있는 사용자를 볼 수 있습니다. 사용자추가 및 삭제는 관리자만 가지고 있는 권한입니다. 사용자를 추가할 시, 기본값으로 General User입니다.

    아래 표는 역할 별 부여된 권한입니다.

    역할설명
    Administrator관리자는 다른 테스트나 스크립트들을 볼 수 있고 모든 유저로 사용자 전환이 가능합니다. 또한 에이전트들을 승인하고 시스템 설정을 변경할 수 있습니다.
    Super User슈퍼 유저는 다른 테스트나 스크립트들을 볼 수 있고 모든 유저로 사용자 전환이 가능합니다.
    System User시스템 내부적 사용을 위해 예약되어 있습니다. (Reserved for system internal use)
    General User일반 유저는 본인의 테스트와 스크립트만 볼 수 있습니다.

    로그 파일

    nGrinder의 로그는 controller쪽에만 존재하며 컨테이너 내부 log 경로는 다음과 같습니다.

    $ /root/.ngrinder/perftest

    성능 테스트한 결과의 순번대로 쌓이며 0~999까지의 숫자가 0_999 폴더에 쌓입니다.

    테스트


    테스트는 로컬환경에서 1core/1g 1개, 1core/2g 1개, 1core/4g 1개 ,2core/2g 1개, 2core/4g 1개로 http://www.google.com/에 대한 부하 테스트를 실행하였습니다. 테스트 스크립트는 기본으로 제공해주는 Groovy를 사용했습니다.

    부하 테스트시, 데이터 유실이 다음 2가지로 생길 수 있습니다.

    1. 초당 전송되는 에이전트 CPU/ 메모리 수치
    2. 초당 전송되는 샘플링 결과

    동시접속이 많을 시, 서버가 뻗어서 다량의 에러로 멈출 수도 있지만, 에이전트의 성능이 부족하여서 에러가 날 수도 있습니다. 또한 하나의 에이전트에서 많은 vuser를 생성한 경우, 쓰레드의 갯수가 한번에 많이 생성되어 cpu사용률이 확 올라가기 때문에 뻗을 위험도 있습니다.

    로컬

    테스트는 다음과 같이 진행했습니다. (전체 실행 횟수의 30%이상 에러가 나오면 테스트가 중지 됩니다.)

    컨테이너프로세스 갯수스레드
    501001502003004005006001000
    agent_1c1g1OOOO에러발생 후 종료



    agent_1c2g1OOOO1c1g보단 성공률 높지만 에러발생 후 종료



    agent_1c4g1OOOO에러율 20%에러 발생 후 종료


    agent_2c2g1OOOOOO에러 2~ 70개 사이에러 발생 후 종료
    agent_2c4g1OOOOOO에러 0~10개 사이1분간 실행 시, 에러 0~100개 사이성공 or 실패

    위 표는 테스트한 결과입니다. 로컬에서 실행해서 부정확한 결과가 나왔습니다. 2core에 메모리 4gb로 1개의 프로세스에서 1000개 쓰레드를 실행 시, 에러를 뱉으면서 테스트가 성공하는 반면, 로컬 피씨가 느려졌을 때 테스트를 시도하면 cpu가 버티지 못해 뻗는 경우가 생겼습니다.

    agent의 사양을 2core에 메모리 1g로 세팅 후, 실험 결과 1core 메모리 4g보다 더 많은 스레드를 수용하여 에러를 적게 뱉었습니다. 이유는 프로세스의 갯수가 많아지면 메모리 사용량이 늘고 쓰레드의 수가 늘어나면 cpu의 사용량이 많아지기 때문에 프로세스 1개로 고정한 후, 쓰레드의 수를 늘리면 2core 메모리 1g의 컨테이너가 1 core 메모리 4g보다 더 성능이 좋습니다.

    2core 메모리 4g의 agent 경우, 1000명의 가상 유저(thread)로 thread마다 각 6번 씩 실행하도록 설정하여 테스트를 했을 때, 에러를 뱉으면서 성공한 것을 확인했습니다.


    agent의 성능을 올리기 위해 open file과 max user process의 갯수를 수정하고자 아래와 같이 명령어를 실행해 확인했습니다.

    $ ulimit -a
    core file size          (blocks, -c) 0
    data seg size           (kbytes, -d) unlimited
    scheduling priority             (-e) 0
    file size               (blocks, -f) unlimited
    pending signals                 (-i) 7907
    max locked memory       (kbytes, -l) 64
    max memory size         (kbytes, -m) unlimited
    open files                      (-n) 1048576
    pipe size            (512 bytes, -p) 8
    POSIX message queues     (bytes, -q) 819200
    real-time priority              (-r) 0
    stack size              (kbytes, -s) 8192
    cpu time               (seconds, -t) unlimited
    max user processes              (-u) 1048576
    virtual memory          (kbytes, -v) unlimited
    file locks                      (-x) unlimited
    

    하지만 ngrinder의 컨테이너는 다음과 같이 이미 10000이상의 숫자가 설정되어 있었고 coreos의 경우 openfile이 1024로 설정되어있어 이를 10000이상의 수로 변경했지만 성능엔 차이가 없었습니다.

    서버

    서버환경에서는 로컬에서 테스트한 것과는 다르게 프로세스의 수도 변경하여 테스트 하였습니다. 


    ipport
    controller

    ip주소 1

    80
    agent001

    ip주소 2


    agent002

    ip주소 3



    컨테이너프로세스스레드
    300
    agent001101분간 실행하여 에러 1개
    agent00210

    에이전트 2개를 연결하여 한꺼번에 프로세스 10개, 스레드 300개를 1분 간 실행했습니다. (총 vuser 6000) 로컬과는 다르게 아래와 같이 에러 1개만 뱉어내며 잘 동작하는 것을 확인할 수 있었습니다.



    다음 vuser 제한을 50000으로 풀어 다음과 같은 스펙으로 실험했습니다.

    컨테이너프로세스스레드
    500
    agent001101분간 실행하여 에러 9개
    agent00210


    동작 시간을 1분이 아닌 2분으로 진행했을 때, 1분 13초 경 메모리 부족 문제로 중지가 되었습니다.


    다음 아래와 같은 스펙으로 실험을 진행했습니다.

    컨테이너프로세스스레드
    700
    agent00110메모리 부족문제로 중지
    agent00210


    메모리가 부족하여 중도 중지 되었습니다.

    결론

    에이전트의 메모리/CPU와 스크립트가 얼마나 무거운지에 따라 수용할 수 있는 vuser가 다르다는 것을 알 수 있었습니다. 아주 간단한 REST Call의 경우 Groovy 스크립트를 사용하면 1개의 에이전트 (2 core/ 4G)당 5~8000 vuser를 견딜 수 있다고 하는데 직접 해본 결과로는 한 개의 에이전트가 1분간 5000유저를 견디는 것은 가능하지만 그 이상의 시간이 되면 메모리 부족 문제로 중지되는 것을 확인했습니다. 이러한 문제를 해결하기 위해선 테스트 시나리오를 작성한 다음, think time을 넣어 더 많은 사용자를 받을 수 있도록 해야 될 것 같습니다.

    댓글