[Spring Boot] Jmeter로 STOMP 부하 테스트 하기

이민우·2023년 10월 16일
5

🔎 도입

일반적인 HTTP 부하테스트는 참고할 예제가 많지만, 웹소켓 부하테스트는 참고할 문서나 예제가 별로 없었습니다. 이 포스팅을 통해 , 제가 겪었던 문제테스트 플로우를 잘 정리해보겠습니다🙏

현재 진행중인 프로젝트에서 Stomp+SOCK.js를 통해 채팅 서비스를 구현하였습니다. 프로젝트 시작전에 중점을 둔 사항이 채팅 서비스의 성능 튜닝이 였습니다.

우선 성능 튜닝을 하려면 현재 성능 파악과 개선할 문제점을 찾아야합니다! 부하테스트를 진행하기 위해 jMeter 를 사용해 보겠습니다.

JMeter 사용해보기

JMeter의 설치와 실행


Apache JMeter Download page

공식 홈페이지에서 zip 파일을 다운받습니다.

압축을 풀면 bin 폴더에 jmeter.sh 파일과 jmeter.bat 파일이 있습니다.
맥에선 sh파일로, 윈도우에선 bat파일을 실행하면 됩니다.

별다른 설정을 하지 않았는데 처음부터 한글로 실행되었습니다.
간단하게 설치와 실행이 완료되었습니다.

(brew를 사용하신다면 brew install jmeter 를 사용할 수 있습니다.)

실행

  • 설치된 경로로 가서 jmeter 입력해주면 GUI환경이 실행됩니다!

테스트 실행


쓰레드 그룹 생성하기
  • Test Plan 우클릭 -> Add -> Threads -> Thread Group을 선택하여 쓰레드 그룹을 생성합니다.

  • Number of Threads : 테스트를 실행할 유저수
  • Loop Count : 한 유저당 반복할 횟수를 지정합니다

STOMP+웹소켓 부하테스트

일반적인 HTTP 부하테스트는 참고할 예제가 많지만, 웹소켓 부하테스트는 참고할 문서나 예제가 별로 없었습니다ㅜㅜ 이 포스팅을 통해 잘 정리해보겠습니다!!

⚙️ 세팅

먼저 jMeter에서 웹소켓 테스트를 하기 위해서는 , 웹소켓 플러그인을 설치해야합니다.

  1. jMeter에서 Options -> Plugins Manager
  2. WebSocket Samplers by Peter Doornbosch를 검색해서 설치!

📝 전체 테스트 플로우


전체적인 테스트 플로우이다. 커넥션이 성공하면, 구독을 하고 채팅방에 입장함과 채팅을 보내고 보냈던 메시지를 받으면 성공이다.

1️⃣ WebSocket Open Connection

  • 웹소켓 연결을 위해서 Thread Group 우클릭 -> Add -> Sampler -> WebSocket Open Connection

  • Server name or IP : 서버네임(저는 localhost로 진행했습니다)
  • Port : 포트번호
  • Path : STOMP 연결할 Path

📌 문제 상황 발생

여기서 Stomp와 연결할 보통 경로는 '/ws-stomp 입니다. 그래서 경로를 /ws-stomp로 설정해줬는데 400 Error가 발생했습니다...

👨🏻‍💻 문제 해결

프로젝트에서 채팅 할때, websocket 연결하는 순간, 개발자 도구를 확인해보니

경로가 ws-stomp/유저번호/세션 식별자/websocket인걸 확인 할 수 있었다(이걸로 몇일 고생,,)

그래서 WebSocket Open Connection경로는

/ws-stomp/${counter}/${__RandomString(8,abcdefghijklmnopqrstuvwxyz,sessionld)}/websocket

설정해주면 됩니다

  • ${counter} : 유저 번호 변수
  • ${__RandomString(8,abcdefghijklmnopqrstuvwxyz,sessionld)} : 세션 식별자 랜덤 생성

+) 여기서 counter는 제가 따로 JMeter에서 설정한 변수 입니다!

2️⃣ Send Connect

Websocket이 연결된 후, 클라이언트는 다음과 같은 형태로 요청을 할 수 있다.


Request Data

["CONNECTED\nversion:1.1\nheart-beat:0,0\n\n\u0000"]

가능한 헤더

  • accept-version : 클라이언트가 사용한 버전
  • host : 클라이언트가 연결하려는 가상 호스트의 이름
  • login : Secured Stomp Server와 연결하기 위한 사용자의 id
  • passcode : Secured Stomp Server와 연결하기 위한 사용자의 비밀번호
  • heart-beat : heart beat 세팅
    • client는 heart-beat:cx,cy 형태로 요청을 보낸다.
    • server는 heart-beat:sx,sy 형태로 응답을 보낸다.
    • x는 outgoing hear-beat, y는 incoming hear-beat이다.
    • heart-beat : cx,cy 형태로 세팅하며, Max(cx,sy) millesecond 마다 heart-beat를 주고 받아 상태를 체크한다.

정상적으로 연결이 되면 다음과 같은 메시지를 서버로부터 응답받는다.

3️⃣ SEND SUBSCRIBE

  • Subscribe 요청으로 해당 큐를 구독하고, 메시지를 수신받을 수 있다.

    Request Data

    ["SUBSCRIBE\nid:sub-1\ndestination:/sub/chat/room/d31e42b0-5ff6-4091-b038-7c9351a7e45e\n\n\u0000"]

  • id : 무조건 포함시켜야 하는 헤더로, 클라이언트가 구독한 큐가 여러개일 때 이를 구분하기 위한 id이다.

  • destination : 구독하려는 큐의 이름(구독할 경로를 지정해주면 됩니다)

4️⃣ ENTER (채팅방 입장)


Request Data

["SEND\ndestination:/pub/chat/enterUser\ncontent-type:application/json\n\n{\"roomld\":\"d31e42b0-5ff6-4091-b038-7c9351a7e45e\",\"type\":\"ENTER\",\"sender\":\"mm\"}\n\u0000"]

  • destination : 보내려는 지점(큐)
  • content-type : 데이터 타입

5️⃣ SEND CHAT (채팅 보내기)

Request Data

["SEND\ndestination:/pub/chat/sendMessage\ncontent-type:application/json\n\n{\"roomId\":\"d31e42b0-5ff6-4091-b038-7c9351a7e45e\",\"type\":\"TALK\",\"sender\":\"mm\", \"message\":\"부하테스트\"}\n\u0000"]

  • destination : 보내려는 지점(큐)
  • content-type : 데이터 타입
  • 위 예제의 경우, 전달되는 메시지는 "부하테스트" 가 됩니다.

6️⃣ DISCONNECT

👨‍🏫 수행 결과 분석

  1. 총 샘플 수 (Total Samples): 1000
    • 10명의 유저가 10번씩 요청을 보냈기 때문에, 총 1000번의 요청
  2. 평균 응답 시간 (Average): 7501ms (7.501초)
  3. 최대 응답 시간 (Max): 25011ms (25.011초)
  4. 에러율 (Error %): 0.00%
  5. 처리량 (Throughput): 1.3/sec
    • 초당 평균적으로 1.3개의 요청이 처리

분석

평균 응답 시간이 무려 7.5초,,,(10명의 사용자가 10번 요청 보냄)
따라서 이 부분에서 성능 최적화가 필요할 수 있습니다.

참고


stomp+부하테스트

profile
백엔드 공부중입니다!

2개의 댓글

comment-user-thumbnail
2024년 11월 5일

자료가 없는 내용인데 대단하십니다!!!

1개의 답글