코테이토 내 실시간 선착순 문제풀이 서비스를 개발한 지 1년 정도 됐다. 웹소켓을 활용해 관리자가 버튼을 클릭할 시 실시간으로 접속한 사용자들에게 동시에 문제 풀이가 가능하게 했다. 하지만 현재 웹소켓 전송 로직을 바꿀까 고민중에 있어 글을 정리하고자 한다.
현재 선착순 제어 로직은 다음과 같다.
- 관리자가 접근 버튼을 누른다.
- 웹소켓을 이용해 접속한 모든 사용자에게 해당 퀴즈 pk가 넘어간다. 문제의 데이터는 보내지 않는다.
- 사용자는 웹소켓으로 받은 퀴즈 pk를 Body에 넣어 퀴즈의 정보를 받는 API를 쏜다.
Response DTO
해당 로직은 장단점은 다음과 같다.
장점
- 웹소켓을 통해 적은 메세지만 보내므로 모든 인원이 비슷한 시기에 버튼을 받을 수 있다.
단점
- 웹소켓 → API → 랜더링의 과정을 겪으므로 시간이 오래 걸린다.
- API(문제 정보를 받는)는 각 클라이언트 마다 진행하므로 1번의 문제마다 사람 수 만큼의 API 요청이 들어가게 된다.
따라서 해당 문제를 해결하기 위해 다음과 수정된 로직을 구상했다.
- 웹소켓을 이용해 quizId와 동시에 퀴즈 정보에 대한 데이터도 같이 넘긴다.
- 받은 데이터를 기반으로 랜더링한다.
먼저 K6 테스트를 통해 두 로직의 실행 시간 차이가 얼마나 있는지 확인했다.
아래는 K6 테스트 결과를 정리한 글이다.
https://ghcodenote.tistory.com/38
결론만 말하자면 수정한 로직이 기존 로직보다 빠른 것을 확인할 수 있다.
해당 테스트를 기반으로 프로젝트 회의 때 웹소켓 수정 계획을 발표하였다.
이야기를 듣고 한 팀원의 질문이 들어왔다.
“웹소켓으로 문제의 정보를 다 보내는 것이 웹소켓의 역할을 다 하는건가요? ”
그 전까지 속도와 효율성만 생각했지 웹소켓의 역할에 대해 고민해보지 않았었다. 그래서 해당 내용이 웹소켓과 맞는 내용인지 공부하게 됐다.
웹소켓의 목적
웹소켓의 가장 큰 특징은 양방향 실시간 통신이다. 주기적으로 변하는 동적 데이터를 실시간으로 반영하기 가장 좋은 기술이다. ex) 채팅, 남은 시간, 보고 있는 고객 수 등등
현재 실시간 퀴즈에서 가장 동적으로 적용돼야 하는 것은 두 가지다.
- 문제 정보가 관리자의 제어에 실시간으로 바뀌어야 한다.
- 동시에 문제 풀이가 활성화되어야 한다.
하지만 문제가 바뀌기만 하면 됐지 랜더링까지 같아야 될까? 라는 고민을 했다.
문제에 대한 정보는 정적인 요소이다. 한번 문제를 업로드하면 그 정보는 CS 퀴즈가 진행되는 동안 바뀌지 않는다. 그 정적인 요소를 동적 데이터를 전송하는 목적을 가진 웹소켓에 사용해야 할까? 라는 고민을 하게 된다. 그 것만의 이유로는 웹 소켓에 퀴즈 데이터를 넣을 필요가 없다고 생각이 든다.
문제 풀이에 대한 제어는 추가로 API를 요청할 필요가 없기 때문에 어떤 방법으로 하더라도 상관 없다.
동일한 API가 여러 번 요청 된다.
그러면 다음 문제점인 “문제마다 사람 수 만큼의 API 요청이 추가로 들어가게 된다”를 생각 해보자.
현재는 다음과 같이 정적인 퀴즈 정보를 사용자 수 만큼 보내야 한다. 해당 로직은 소켓에 접속한 사용자가 N명이라 할 때, 한 문제를 보낼 때마다 API 요청과 DB 쿼리 모두 N번씩 생기게 된다.
이것은 확실히 비효율적인 로직이라 생각이 든다. 하지만 이를 해결하기 위해 웹소켓에 퀴즈 정보까지 넣어야 할까?라는 고민이 있다.
두 방법 말고 다른 방법도 생각해보았다.
- 최초 소켓 접속 페이지에 도달할 시 API를 활용해 10개의 문제 정보를 모두 받는다. 그 후 소켓으로부터 quizId의 정보를 받으면 미리 받았던 정보 중에 해당하는 문제를 랜더링한다.
하지만 이 방식은 개발자 도구를 까게 되면 미리 문제를 확인할 수 있어 형평성에 문제가 있을 수 있다고 생각이 들어 자체 기각하였다.
일단 정리한 내용을 팀원들에게 전달하고 어떤 방법이 좋을 지 이야기하고 게시물에 추가할 예정이다
'COTATO.KR 프로젝트' 카테고리의 다른 글
[Spring] Params를 통한 동일 path API 구분 + Swagger에서 불가능한 이유 (1) | 2025.02.15 |
---|---|
[K6 테스트] websocket 발전을 위한 성능 테스트 (0) | 2024.08.22 |
Multipart/form-data convert(역직렬화) 오류 해결 (0) | 2024.08.06 |
코테이토 홈페이지 프로젝트 V1 회고록 (0) | 2024.06.03 |