Skip to content

성능테스트 환경 구축 #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
5 tasks done
junha-ahn opened this issue Aug 18, 2023 · 2 comments
Closed
5 tasks done

성능테스트 환경 구축 #32

junha-ahn opened this issue Aug 18, 2023 · 2 comments
Assignees
Labels
documentation Improvements or additions to documentation Major Major topic

Comments

@junha-ahn
Copy link
Member

junha-ahn commented Aug 18, 2023

Description

해당 문서는 학습용 Document

실제 성능테스트 스크립트 작성은 f-lab-clone/ticketing-backend#83 에서 진행

1. Database를 초기화한다

1

2. K6를 통한 성능테스트를 진행한다

2

3. Grafana 대시보드를 통해 결과를 확인한다

3

To do

  • 트래픽 시나리오 테스트 가능화
  • 자동화 고려

Test Checklist

  • 가장 간단한 테스트 시나리오 작성 (로그인 후 예약)
  • 실행
  • 결과 확인 가능화
  • 결과 슬랙 전송
@junha-ahn junha-ahn added the Major Major topic label Aug 28, 2023
@junha-ahn junha-ahn moved this to Todo in Kanban Infra Aug 28, 2023
@junha-ahn junha-ahn moved this from Todo to In Progress in Kanban Infra Aug 31, 2023
@junha-ahn
Copy link
Member Author

junha-ahn commented Aug 31, 2023

성능 테스트 전반적 개념 학습

접기/펼치기

[우아한테크] 10분 테크톡 성능 테스트

  • 병목 현상을 확인하고 개선하는 것이 목적
  • 임계치 이상의 과부하 상태에서 어떻게 동작하는지 확인 (장애, 자동복구 등)

부하테스트/스트레스테스트 용어의 정의는 무시. '성능 테스트'로 통일
각 용어 정의에 대해서는 이 글을 참고

[엘리스 CTO가 알려주는 ‘서버 성능 측정 방법’

](https://www.youtube.com/watch?v=HSNyJnobBws)

image

어느 서버가 더 성능이 좋은가

  1. 10명이 동시에 호출했을 때 1초 안에 모두가 응답을 받음
  2. 100명이 동시에 호출했을 때 10초 안에 모두가 응답을 받음

Latency : 사용자의 입장에서 응답에 걸리는 시간
Throughput: 작업자의 입장에서 시간당 얼마나 처리하는가

테스트 시나리오

10개의 커넥션 5초동안 연결

  • Latency 11.5 ms
  • 종합해서 1초에 885개의 Request 처리

100개의 커넥션을 5초동안 연결

  • Latency 104 ms
  • 1초당 950개의 Request처리

그렇다면 "우리 서버는 동시에 950명이 접속해도 안전합니다"라고 말 할 수 있는가?

  • 각 유저들은 속도가 느려지는 등...

이건 그저 "서버가 버틸 수 있을때까지 최대한 Request를 넣어보는 행위"

  • 서버의 한계치를 알 수 있지만, 동시접속자를 몇명까지 받을 수 있냐에 답은 아니다.

테스트 시나리오 개선

"100명의 유저가 30초동안 Request를 하는데, 인당 1초에 1번씩 Request를 한다"

  • 집중하는것은, 사람들이 API에서 response를 받는데 얼마나 걸리는가
  • 위 테스트는 얼마나 처리할 수 있고, 그때 Latency가 얼마인가
  • 이번 테스트는 "얼마나 처리할 수 있나"를 고정하고 그때 Latency가 얼마나 빠른가

1초에 100개씩했을때 Latency가 3ms, 10배를했을때 Latency가 1s

  • Request는 10배가 늘어났는데 Latency는 300배 느려졌다

어떻게 개선하는가?

  1. 서버 대수를 늘린다.
    image
    image

  2. 코드를 효율화한다.

image

그래서 우리는 어떻게 할 수 있을까?

image

  1. 현실적인 성능 측정 지표를 설정하고 성능을 개선한다
  2. 서버 대수를 최대한 억제하고, 로직을 개선한다.
  3. 서버 대수의 증가로 변화하는 처리능력을 측정한다
  4. "성능 기준"을 정하고 Git actions를 통해 테스트 자동화
  5. 서버 구조의 변화를 준다. [우아콘2020] 배달의민족 마이크로서비스 여행기 참고

일단 2번까지 도달했으면... 4번의 경우는 너무 긴 여정이 될 것 같다.

[우아콘] 서버 성능테스트, 클릭 한 번으로 끝내볼 수 있을까

접기/펼치기

반복되는 부분

image

자원 생성

image

테스트 후 결과 기록

image
image

자원 정리

image

@junha-ahn junha-ahn self-assigned this Aug 31, 2023
@junha-ahn junha-ahn added the enhancement New feature or request label Aug 31, 2023
@junha-ahn
Copy link
Member Author

junha-ahn commented Sep 8, 2023

어떤 성능테스트 도구를 사용할 것인가?

기준

  • 현재 인프라 환경에 가장 어울리는 도구 (EKS, Prometheus + Grafana, JVM/Kotlin + Spring Boot)
  • 시나리오를 통한 테스트 가능
  • (향후) 성능 테스트 자동화에 적합

참고

K6를 사용한다

  • EKS, Prometheus + Grafana 환경에 적합하다
  • Export And Monitor k6 Results (Grafana 뿐 아니라, CSV, Datadog, AWS cloud watch, Kafka, InfluxDB 등등으로 Export 가능)
  • K6는 Javascript로 쉽게 작성하고, Go로 실행한다 - About the Go-to-JS bridge
  • Stage 기능 등을 통해 여러 시나리오 테스트 가능
  • 향후 성능 테스트 자동화에 적합하다 (Docker image 존재, 의존성 없음, K6 cloud 존재 등)
    • thresholds 를 통해 "1000명의 동시접속자에 대해 100ms의 최대 Latency 유지" 등의 Desired State 정의 가능 (어느정도의 성능 개선과 목표 달성 후 해당 "성능"을 전반적 유지를 위해 사용 가능)

성능 (single k6 instance)

  • 동시에 30k ~ 40k 유저를 컨트롤 가능 (VUs)
  • 300k request per second
  • 6M~12M request per minute
  • 위 성능을 위해 (쉬운) OS 최적화 필요 (Docs 존재)
  • CPU보단 RAM에 따라서 성능이 달라짐

언제 성능테스트를 자동화를 할 것인가?

성능 최적화 이후 "일정 성능 유지"를 위해 자동화한다

  • thresholds 를 통해 Success/Fail 판단하는 등
  • Git actions 를 통해 자동화 가능

애플리케이션 환경 구성

EKS Cluster를 환경에 따라 구분하지 않는다.

해당 프로젝트의 목적은 '성능테스트' 자체에 있기 때문에 PROD/DEV 환경등의 이중 구성이 필요하지 않다.

문제점

  • 만약 동시에 성능 테스트가 진행되면 테스트 결과가 오염된다 (예를들어 테스트 당시의 DB CPU Usage 등)
  • 이는 매 테스트마다 환경을 생성하는게 아니면 발생할 수 밖에 없는 문제이다.
  • 해당 프로젝트에서는 비용 이슈가 더 중요하기 때문에 'Lock' 과 같은 방식을 고려해볼 수 있다.
    • DynamoDB등에 performanceTestLock 을 구성하고 테스트를 진행하는 등
  • 다만 이는 사이드프로젝트 레벨에서 중요하지 않은 문제이기에 고려하지 않는다.

애플리케이션 초기화 문제

동일한 환경에서 어떻게 여러번의 부하 테스트를 진행할것인가? 즉 어떻게 초기화할 것인가?

애플리케이션 리소스와 모니터링 환경 및 데이터는 그대로 유지. 그 외 Stateful 리소스의 Data 초기화

  • 즉 DB를 매 테스트 전후 Clean up 한다. (현재 DB가 유일한 Stateful 리소스)
  • 따라서 리소스의 재생성 없이 테스트 환경 세팅이 가능하다

향후 제약사항

  • 현재 DB는 AWS private subnet에 존재.
  • Bastion Host를 통해 SSH Terneling 환경 구성 완료
  • 향후 테스트 환경 구성시 DB 접근이 가능한 VPC 내부이거나 BationHost PublicKey가 필요하다.
  • 위 사항에도 불구하고, 매번 쉽게 실행이 가능해야 한다. (= DB 초기화 자동화)

테스트 환경

고려대상

  • k6 cloud
  • aws-ec2-same-vpc
  • aws-ec2-another-vpc
  • local

결정

  • 같은 VPC 내부에서는 테스트를 진행하지 않는다. 최대한 사용자의 접속 환경과 유사하게 구성한다.
  • Local 환경에서 부하를 만들어내고, 만약 리소스가 부족하다면 K6 Cloud와 ec2-another-vpc(by terraform) 중 고민한다.

어떤 레포지토리에서(Infra/Backend) 테스트 스크립트를 작성할 것인가?

향후 Git Actions 테스트 자동화를 위해서는 Backend를 사용한다

  • 개발자가 코드 수정 후, 그에 따른 성능 저하가 없음을 확인 한다.
  • 물런 인프라 환경 구성의 변화로도 성능 변화가 발생할 수 있다 (하지만 애플리케이션 코드를 우선한다)

로컬에서 DB를 어떻게 초기화할 것인가?

cleanup endpoint를 만든다면?

  • 해당 endpoint를 요청하는 것만으로도 쉽게 Database를 초기하 가능 (즉 Pem Key 전달이 필요 없다)
  • 다만 누구나 호출하면 안되기 때문에, 요청 권한 문제 발생
  • 따라서 결국 Publickey와 동일하다

자동화 스크립트를 구현한다

ticketing-backend/
    load-test/
        bastion.pem # 인프라개발자에게 전달받는다
        run.sh 
        k6-scripts/ 
        db-init/ # db init scripts...

실제 구현시 최대한 의존성을 제거하고, 자동화한다

어떻게 테스트 결과를 출력할 것인가?

두가지 테스트 결과가 존재한다.

  1. 해당 테스트 중 애플리케이션 리소스에서 발생하는 여러 매트릭 (App, DB 상태 등)
  2. K6가 출력하는 결과 (생성한 Virtual User, TPS 등)
    • 물런 TPS와 같은 몇몇 정보는 1번에서도 확인 가능하지만, K6가 출력하는 데이터는 엔드유저 관점

image

K6 Report

애플리케이션 리소스 정보는 어떻게 확인하는가?

  • Grafana Dashboard Link와 Time Range Query(dashboard.com?from=...&to=...) 를 출력한다.
  • 이때 클러스터 노드, 스프링 App, DB 등의 대시보드를 출력한다.

K6테스트 결과는 어떻게 확인하는가?

  • 먼저 해당 정보는 stdout으로 출력된다.
  • 하지만 K6 테스트 결과 중 매트릭(시계열 데이터)을 쉽게 확인하기 위해 K6 Grafana Dashboard를 구성한다.

Todo

  • K6 문서 리딩
  • Backend Repo Docker-compose (db init, k6 script) 작성
    • Docker-compose Run
    • DB init
    • K6 Run
    • Prometheus Remote Write (Ingress Controller)
  • Print Grafana Dashboard (Time Range)
    • K6 Metric Output
    • Monitoring Report

@junha-ahn junha-ahn added documentation Improvements or additions to documentation and removed enhancement New feature or request labels Sep 21, 2023
@junha-ahn junha-ahn changed the title 부하테스트 환경 구축 성능테스트 환경 구축 Sep 21, 2023
@github-project-automation github-project-automation bot moved this from In Progress to Done in Kanban Infra Sep 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation Major Major topic
Projects
Status: Done
Development

No branches or pull requests

1 participant