Algo With Me는 모두가 참여하고 만들 수 있는 알고리즘 대회 서비스입니다.
주요 기능은 다음과 같습니다.
- 사용자가 제출한 코드를 채점할 수 있습니다
- 실시간으로 대회에 참여한 경쟁자들의 순위를 확인할 수 있습니다
_.mp4
대회 페이지는
- 문제 화면
- 코드를 작성할 수 있는 에디터
- 제출 결과 화면
으로 구성됩니다.
나만의 테스트 케이스를 추가하고 "테스트 실행"버튼을 눌러 실행할 수 있습니다.
"제출하기" 버튼을 누르면 히든 테스트 케이스들의 정답 여부와 시간, 메모리 사용량을 받아볼 수 있습니다.
대회 참여자 순위 100위까지와, 나의 순위를 대회 진행 중 실시간으로 확인할 수 있습니다.
대회 참여자가 아니라도 대시보드를 확인할 수 있습니다.
저희 팀에게 주어진 자원은 2코어, 8GB RAM 네이버 클라우드 인스턴스 하나였습니다.
하지만 부스트캠프 전원(200명)이 참여할 수 있는 서비스를 만들고 싶었습니다.
그래서 가진 자원을 어떻게 해야 최대한으로 활용할 수 있을까 라는 도전과제를 목표로 설정하게 되었습니다.
어떻게 많은 채점 요청이 들어오더라도 누락 없이 모두 채점할 수 있을까?
어떤 기술을 사용해야 우리 문제를 해결하는 데에 유리할까?
병렬적으로 채점하려면 어떻게 구조를 짜야 할까?
보안 위협 없이 안전하게 채점할 수 있을까?
폴링, 웹 소켓, SSE 무엇을 사용해야 할까?
DB, 메모리 자원을 어떻게 효율적으로 활용할 수 있을까?
어떻게 해야 서버 부담을 줄이면서도 실시간으로 데이터를 전달할 수 있을까?👉 대시보드 데이터 redis 저장 방식, 클라이언트에게 보낼 양식, db 저장 방식
👉 대시보드 소켓 재사용 관련 회의
어떻게 해야 서버로 가는 요청을 줄여서 리소스를 아낄 수 있을까?
채점은 몰라도 테스트 정도는 클라이언트에서 돌려도 되지 않을까?
Eval을 사용하면 될 것 같긴 한데, Eval을 써도 될까?
Eval을 사용하면 무한 루프를 만났을 때 메인 스레드가 멈추는 문제가 생긴다.
웹 워커를 이용해서 스레드를 분리해 보자
Eval은 언제 위험할까?
Eval은 사이드 이펙트가 발생할 때 위험해
사이드 이펙트가 일어날 수 없는 순수한 JS 엔진을 올려서 사용해 보자
QuickJS라는 JS 엔진을 사용하면 될 것 같아.
하지만 이게 정말 모든 브라우저에서 공평하게 동작할까?👉 [검증] QuickJS는 모든 브라우저에서 동일한 성능을 보장할 수 있는가?
👉 [검증] QuickJS는 모든 브라우저에서 동일한 Max Call Stack을 보장할 수 있는가?
참여자들은 시험이 정확하게 같은 시간에 시작하고 같은 시간에 끝나기를 기대한다.
이를 위해서 서버와 클라이언트의 시간을 동기화해야 하는데, 어떻게 할 수 있을까?
서버 자원이 무한하다면 1초마다 Http 요청을 보내면 되지만, 서버 자원은 한정되어 있다.
클라이언트의 Date 객체만으로는 서버와 시간 동기화할 수 없을까?
브라우저의 Date 내장 객체로는 엄밀한 시간 동기화가 불가능해
5초 간격으로 시간을 갱신해주는 정도로 요청을 최소화해볼 수 있을까?
setInterval은 얼마나 믿을 수 있을까?
대시보드 데이터 관리를 위해 Redis를 설치하려고 했다.
NestJS에서 제공하는 cache-module을 사용했는데, Redis에 특화된 자료구조를(e.g. SortedSet) 제어하는 명령어를 사용할 수 없었다.
redis-client를 설치하여 문제를 해결했다.
일부 채점 결과가 누락되는 문제가 발생했다.
채점이 병렬적으로 진행되어 API 서버에 요청이 거의 동시에 들어왔고, 경쟁 조건이 발생했기 때문이었다.
트랜잭션을 걸었지만, 문제는 해결되지 않았고, 락을 건 이후에야 제대로 동작했다.
기존에는 root 사용자로 모든 서버를 운영하고 있었다.
보안상의 이유로 코드 실행 서버의 유저 권한을 root에서 일반사용자로 바꾸었는데, 권한이 줄어들어 파일 읽기 쓰기가 되지 않는 문제가 발생했다.
도커 유저 설정을 통해 API 서버와 채점 서버의 권한을 일반 사용자로 바꾸어 문제를 해결했다.
socket으로 데이터를 받아 대시보드를 모달로 보여줘야지
모달을 닫고 다시 열면 데이터가 정상적으로 수신되지 않아
페이지에서는 정상 작동하는데, 모달에서는 왜 작동하지 않을까?
통신 오버헤드를 줄이기 위해 웹 소켓을 사용하기로 결정했다.
개발자 도구로 웹 소켓 연결을 확인하니 10개의 웹 소켓이 연결되는 것을 확인했다.
무엇이 문제고, 어떻게 해결해 나가야할까?
Netlify에 웹페이지는 배포를 마쳤다.
하지만 메인 페이지를 제외한 다른 페이지에서 새로고침을 하면 404 페이지가 나오는 문제를 겪게 된다.
개발 환경과 배포 환경은 무엇이 달라 이런 문제가 생겼을까? 어떻게 해결할 수 있을까?
JMeter로 부하테스트를 수행하여 부스트캠프 전 인원이 우리 서비스를 이용할 수 있을지 알아보았다.
200명이 동시에WebSocket
을 통해 대시보드 데이터를 원활하게 받을 수 있음을 확인하였다.
그리고, 100명이 0~10초 균등확률분포로 코드 제출 요청을 보냈을 때, 채점을 원활하게 할 수 있음을 확인했다.
미니 개발 세미나란?
미니 개발 세미나는 Web12 코드 사피엔스팀 내부에서 공유 문화를 만들기 위해 시작된 소규모 세미나입니다. 5 ~ 10분 동안 자유주제 혹은 프로젝트를 진행하면서 공유하고 싶은 내용을 발표하는 방식으로 진행됩니다. 발표자는 팀원들로 구성되지만, 다른 캠퍼들도 자유롭게 듣고 질문할 수 있도록 외부적으로 공개하였습니다. 2023/11/08 첫 세미나를 시작으로 5회 진행되었으며, 부스트캠프가 끝나고도 이어갈 예정입니다.
썸네일 | 한 줄 소개 | 링크 |
---|---|---|
제가 개발자의 길을 걷게 되면서 스스로 가지고 있던 개발자의 정의가 어떻게 바뀌었는지 회고하고 질문을 던집니다 | 그대들 어떻게 개발할 것인가? | |
양방향 통신들의 기법에 대해서 간략히 알아보고, 왜 우리가 webSocket을 선택했는지 공유합니다. | WebSocket을 선택한 이유 | |
클린 코드를 왜 지향해야 하는지, 클린 코드와 주석의 상관관계는 무엇인지에 대해 설명합니다. | 클린 코드, 주석 | |
MicroService Architecture가 무엇인지, 어떤 장점이 있는지, 언제 사용해야 하는지 살펴봅니다. | Why MSA? | |
대시보드 실시간 갱신을 위해 WebSocket과 Redis를 도입하여 사용하게 된 과정을 소개합니다. | 대시보드 어떻게 구현하지 |
FE | FE | FE | BE | BE |
---|---|---|---|---|
J079 양기조 (dev2820) |
J111 이우찬 (dmdmdkdkr) |
J140 정유석 (mahwin) |
J026 김용후 (rladydgn) |
J109 이예찬 (yechan2468) |