Skip to content
Jooyeob Na edited this page Dec 3, 2024 · 8 revisions


프로젝트 소개

Harmony 는 기존 프로젝트 관리 도구의 불편함을 해결하기 위해 탄생한 실시간 일정관리 서비스입니다.

  • 실시간 일정관리
    기존 일정관리 서비스(Github Project)의 비동기적인 관리 방식을 개선하기 위해 실시간 편집 및 반영을 지원합니다.
  • 플래닝 포커
    별도의 외부 서비스를 이용하는 불편함을 해소하기 위해 플래닝 포커 기능을 지원합니다.


핵심 기능

프로젝트 관리

  • 프로젝트를 생성하고 다른 사용자를 초대할 수 있습니다.
프로젝트 생성 및 초대 초대 승인 및 거절
프로젝트 생성 및 초대 초대 승인 및 거절

실시간 편집 및 반영

  • 태스크를 생성하고 상태를 관리할 수 있습니다.
  • 편집한 내용은 다른 사용자에게 실시간으로 반영됩니다.
실시간 편집 및 반영

태스크 관리

  • 태스크 설명을 작성하고, 하위 태스크를 지정할 수 있습니다.
  • 담당자, 라벨, 우선순위, 스프린트, 예상 작업 시간을 지정할 수 있습니다.
태스크 관리

플래닝 포커

  • 플래닝 포커에 참여하고 카드를 선택해 제안할 수 있습니다.
  • 다른 사람이 선택한 카드를 확인할 수 있습니다.
플래닝 포커

대시보드

  • 프로젝트의 작업 현황, 담당자별 기여도, 우선순위 통계를 확인할 수 있습니다.
대시보드

핵심 경험

Long Polling 을 선택한 이유

실시간 편집 및 반영을 위해 Polling, SSE, WebSocket 중 어떤 기법을 사용할지 고민했습니다.
"직접 경험해보고 판단하자" 라는 팀 목표에 맞게, 실제로 서비스에 다양한 기법을 적용하려 했습니다.
다만, 일정을 고려해서 Long Polling 과 WebSocket 을 사용해보기로 결정했고
서비스의 특성상 높은 실시간성을 필요로 하지 않아 Long Polling 을 먼저 적용해보기로 했습니다.


Long Polling 의 한계

실시간 반영을 위해 두 가지 업데이트 방식을 고려할 수 있었습니다.

전체 업데이트
(선택)
전체 업데이트
부분 업데이트 부분 업데이트

Long Polling 은 재연결 과정에서 이벤트가 누락될 가능성이 있습니다.
이를 고려하여 이벤트를 받아오는 것이 아닌 전체 데이터의 스냅샷 형태로 받고자 했습니다.


하지만, 이 방식은 커서를 강탈당하는 문제가 있어 동시 편집이 불가능했습니다.

동시 편집 불가 사진

그래서 부분 업데이트 방식으로 변경했습니다.
처음에 예상했던 대로 부분 업데이트는 재연결 과정에서의 이벤트 누락이 발생했습니다.

위치 이동 이벤트 누락 초대 승인 및 거절
위치 이동 이벤트 누락 텍스트 편집 이벤트 누락

Long Polling 개선하기

우선, 이벤트의 누락이 얼마나 발생하는지 확인했습니다.
K6 를 활용해 100명의 수신자를 기준으로, 0.1초부터 1초까지 RPS(초당 요청 수)를 조정하며 응답을 성공적으로 수신하는 비율을 측정했습니다.
테스트 결과, 500ms 보다 좁은 간격으로 이벤트가 발생하면 누락률이 급격히 증가하는 것을 확인할 수 있었습니다.

테스트 결과

이를 해결하기 위해 버저닝스케줄링을 적용하고자 했습니다.

버저닝 버저닝
버저닝 스케줄링

타임스탬프를 활용한 버저닝을 적용하여 재연결 사이에 발생한 이벤트들을 목록으로 가져오면 누락을 줄일 수 있을 것이라 생각했습니다.
추가로 Long Polling 의 재연결 횟수를 줄이기 위해 스케줄링을 적용할 수 있을 것이라 생각했습니다.

이 방식을 적용하기 전, 실제 개선 효과가 있을지 검증하기 위해 테스트를 진행했습니다.
이전과 동일한 조건으로 응답을 성공적으로 수신하는 비율을 측정했습니다.

테스트 결과

해당 방식을 적용하면 기존 방식 대비, RPS에 따라 0.4% 부터 최대 16.8% 까지 누락률을 줄일 수 있음을 확인했습니다.
그래서 버저닝스케줄링을 적용해 실제 사용성을 높일 수 있었습니다.



시스템 아키텍처

시스템 아키텍처

기술 스택

분야 기술
공통
FE
BE


팀원 소개

김정한 나주엽 서완석 양희철
BE FE FE BE
jjeonghak PMtHk jjeonghak jjeonghak
jjeonhak PMtHk iam454 yangchef1
Clone this wiki locally