성능 테스트 [대기열] - min429/WEB4_5_ServerSOS_BE GitHub Wiki
성능 테스트
Jmeter, K6는 SSE 테스트를 제대로 지원하지 않는다고 해서 Artillery라는 테스트 도구를 사용했다.
(Jmeter는 SSE 연결 당 스레드 한개 소모로 인해 대량 사용자 테스트 불가, K6는 SSE 연결 유지를 지원하지 않는다고 한다.)
Artillery로 SSE를 테스트할 수 있는 확장 라이브러리
- EventSource를 사용하는데, 기존 소스코드에서 header를 지원하지 않아서 해당 부분만 수정하여 사용했다.
Artillery
테스트 설정 파일
config:
target: http://localhost:8080/api/queue/stream?sessionId=1
http:
defaults:
headers:
Authorization: "Bearer {token}"
processor: /Users/lsm99/artillery-engine-sse/helpers.js # onMessage, onEvent 관련 js 파일
phases:
- duration: 60 # 몇초 동안
arrivalRate: 100 # 초당 몇명의 VU(가상 사용자)를 생성할 지
engines:
sse: {}
scenarios:
- engine: sse
onMessage: handleSSEMessage # eventName이 없는 경우
onEvent: # eventName이 있는 경우
- eventName: wait # eventName이 wait인 경우
handler: onServerTime # 처리할 함수
- eventName: ready # eventName이 wait인 경우
handler: onServerTime # 처리할 함수
flow:
- open
- log: opened # 연결 요청 시 출력
- think: 180 # 연결 유지 시간(초) (서버에서 연결을 끊어도 이 시간 동안은 계속 재연결 시도)
- log: closing # 연결 해제 시 출력
- close
- 테스트 전체 시간은 따로 정의하지 x
- 총 VU 6000명에 대해 각각의 VU가 180초동안 SSE 연결을 유지하도록 함 (서버에 6000명의 SSE가 지속적으로 연결되도록)
- 만약 도중에 연결이 끊겨도 180초 동안은 계속 재연결을 시도함
테스트 결과
All VUs finished. Total time: 4 minutes, 1 second
--------------------------------
Summary report @ 22:35:14(+0900)
--------------------------------
sse.disconnect: ................................................................ 10834
sse.events.server-time: ........................................................ 1084348
sse.open: ...................................................................... 16690
vusers.completed: .............................................................. 6000
vusers.created: ................................................................ 6000
vusers.created_by_name.0: ...................................................... 6000
vusers.failed: ................................................................. 0
vusers.session_length:
min: ......................................................................... 179999.5
max: ......................................................................... 180024.9
mean: ........................................................................ 180001.5
median: ...................................................................... 181743.9
p95: ......................................................................... 181743.9
p99: ......................................................................... 181743.9
- sse.disconnect: SSE 연결이 도중에 끊긴 경우 (이 테스트에서는 대기 완료 시 서버가 끊은 것)
- sse.events.server-time: 받은 SSE 메시지 수
- sse.open: 총 몇번 SSE 연결했는지(재연결 포함)
- sse 연결이 실패할 경우 에러코드와 함께 표시된다. (위 테스트에서는 모두 성공해서 표시되지 않았다.)
- vusers 관련은 본 테스트에서는 딱히 중요한 부분은 아니다.
- 결론: SSE 연결 자체는 모두 성공, 6000명 동시에 SSE 연결이 가능하긴 하다.
- 10초동안 10000명의 사용자 연결도 시도해봤지만, API 요청 시 로그를 기록하는 부분이 있어서 이 부분에 스레드 풀이 꽉차서 병목이 발생했고, 500에러가 발생했다.
- 로그를 기록하는 부분을 제거하고 시도했을 때는 500에러는 발생하지 않았지만, 약 8000명 까지는 연결되고, 그 이상은 연결을 요청해도 응답이 없다(무한 대기). 이유는 모르겠지만 SSE 연결 자체가 약 8000명 까지로 제한이 있는 것 같은 느낌이다. 일단 연결되면 연결 유지 및 메시지 수신은 정상적으로 이루어진다.
Grafana
CPU 사용량
- 테스트 환경이 Mac M2, 12코어인 점을 감안했을 때 단일 서버로는 감당하기 어려워보인다.
- CPU 한계에 거의 다다른 것을 확인할 수 있다.(Spring App이 CPU 2코어 이상 사용했다.)
Thread 수
- 비동기 처리에 사용되는 Thread 수에 제한을 걸어두었기 때문에 임계치 이상에서는 사용량이 같다.