[네이버부스트캠프 웹・모바일 10기] 멤버십 19주차 회고
- 네이버부스트캠프
- 회고

회고를 시작하며
이번 주는 어떻게 보냈는가?
우리 팀은 현재 화상 강의 서비스를 개발하고 있다. 이번 주에는 그중에서도 실시간 미디어 전송 기능을 집중적으로 구현했다. 처음 다뤄보는 기술들이라 복잡하고 어려운 부분이 많았지만, 팀원들과 함께 하나씩 풀어나가면서 서비스의 전체적인 흐름이 명확해졌다.
이번 주말에는 지금까지의 개발 과정을 다시 돌아보고, 서비스 구조를 시각적으로 정리해볼 계획이다. 빠뜨린 부분이나 설계상의 부족한 점들을 찾아내고, 다음 단계로 넘어갈 수 있는 기반을 마련하려고 한다.
지난 주 회고의 피드백
지난 주 팀 회고에 대한 피드백 반영
지난 주 팀 회고에서는 작업 상황의 공유가 잘 되고 있다는 긍정적인 피드백과 함께, 작업 속도가 다소 느리다는 개선 의견이 있었다.
우선 좋은 점이었던 작업 상황 공유는 그대로 이어가고자 했다. 매일 데일리 스크럼에서 작업 내용을 공유하고, 코어타임 중간마다 슬랙으로 진행 상황을 주고받았다. 덕분에 팀원 모두가 서로의 업무 상황을 빠르게 파악할 수 있었고, 팀 내 작업 흐름도 한결 자연스러워졌다.
반면 작업 속도에 관해서는 고민이 많았다. 어떤 부분에서 속도를 늦출까를 생각하며 PR 승인이 조금 늦다는 점을 파악했다. 따라서 이번 주를 시작하면서 조금 더 빠르게 승인하기로 논의했다. 이렇게 하니 다른 사람 작업에 미치는 영향도 줄고, 코드 리뷰도 꼼꼼히 이어가면서 작업 속도까지 개선할 수 있었다.
지난주 개인 회고에 대한 피드백 반영
개인 회고에서 회의 안건을 명확히 정리해서 빠르게 끝내보자는 목표를 세웠었다. 이를 실천하기 위해 매일 스크럼 내용을 전날 밤에 미리 작성해두고, 논의할 주제를 사전에 정리했다. 스크럼 전에 어떤 점들을 다뤄야 할지 미리 살펴보면서 주제에서 벗어나지 않는 빠른 회의를 진행하려고 신경썼다.
그 결과, 회의 시간에 논의할 사항만 딱딱 다루게 되어 이전보다 시간이 확실히 단축됐다. 덕분에 개발에 투자할 수 있는 시간이 늘어나면서 작업 효율도 올라갔다.
또한 이번 주에는 목표를 스토리 형식으로 구체화하자는 내용을 바탕으로, 다음과 같이 목표를 설정했다.

하지만 되돌아보면 이 목표들이 실제 개발 방향에 도움이 됐을까?라는 아쉬움이 남는다. 구체적인 항목을 나열한 건 좋았지만, 개발 과정에서 목표를 자주 참고하지 않았다. 초기 목표 설정으로 끝난 느낌이 강했다.
이번 주 팀 회고에서 목표를 세울 때 더 구체적인 논의를 통해 방향 지표로 삼자는 의견을 나눴다. 단순히 각자 생각나는 걸 적는 게 아니라, 한 주간의 나침반이 되도록 해야 한다는 이야기를 주고받았다. 서로의 작업 상황을 유추하고 보완할 수 있을 것이라는 이야기도 나왔다. 다음 주에는 목표 설정 단계에 더 많은 시간을 투자해야겠다.
저희는 이날, 오픈 스테이지를 할 겁니다.
오픈 스테이지란?
오픈 스테이지는 기술 공유, 이슈 해결 논의, 사용자 테스트 등 무엇이든 시도할 수 있는 열린 공간이다. 캠퍼들과 자유롭게 소통할 수 있고, 프로젝트 관련 발표나 테스트도 가능하다. 특정 파트에 구애받지 않고 모든 캠퍼와 함께 할 수 있다는 게 가장 큰 장점이다.
우리 팀은 화상 강의 서비스를 개발 중이기에, 프로젝트 초반부터 대규모 사용자 테스트를 위해 오픈 스테이지를 계획하고 있었다. 여러 사용자가 동시에 접속했을 때 강의가 원활히 진행되는지 확인하고 싶었기 때문이다.
어떤 계기로 오픈스테이지를 신청하게 되었나?
사실 기능 개발이 예상보다 늦어지면서 테스트 계획이 계속 미뤄졌다. 그러다 보니 오픈 스테이지에 대한 열정도 점점 식어갔고, "언젠가 해야지" 라는 막연한 생각만 남았다. 어느새 4주차가 지나가고 있었고, 프로젝트가 오래 지속되다보니 점점 피로감이 쌓이던 시점이었다.
그때 흘러가는 대로가 아닌 명확한 목표점이 필요하다는 생각이 들었다. 그리고 오픈 스테이지만큼 적합한 목표가 없었다. 팀원들의 열정을 다시 끌어올릴 계기이자, 우리의 노력을 실제로 테스트해 볼 기회라고 생각했다.
그래서 바로 팀원들에게 "오픈 스테이지 날짜를 정하자"고 제안했고, 전체 슬랙 채널에 빼도 박도 못하게 글을 남겨두었다.

무모한 도전은 아닌가?
솔직히 처음에는 무모한 결정이라고 생각했다. 현재 개발 상황으로 정해진 날짜까지 완성할 수 있을까 하는 걱정이 먼저 들었다. 게다가 사전 테스트 없이 100명이 넘는 사용자를 수용할 수 있을지도 확신이 없었다.
처음에는 "다음 주 진행 상황 보고 결정하자"는 의견도 있었다. 하지만 결정적으로 마음을 바로잡을 수 있었던 것은 "부스트캠프라는 특별한 환경" 이라는 점이었다.
실패해도 아무도 뭐라 하지 않으며, 오히려 구체적이고 기술적인 피드백들을 주고받으며 개선할 부분들을 찾을 수 있을 것이라 생각했다. 실패해도 도전 자체에 의미가 있다고 생각했다. 서버가 터지더라도 그 경험을 통해 구체적인 개선점을 찾을 수 있다면 충분히 가치 있을 것이다. 결국 깨지더라도 부딪혀보자는 마음으로 도전을 결심하게 되었다.

오픈스테이지의 목표
첫 번째 목표는 오픈 스테이지를 준비하기로 결정한 것 자체였다. 그 과정에서 어떤 내용을 테스트할지 논의하면서 방향성이 잡혔고, 팀원들 사이에 이왕 이렇게 된 거 더 열심히 해보자는 열기가 돌기 시작했다.
두 번째 목표는 기능 개발 완성이다. 참여자 100명 정도를 감당할 수 있는 서버 구조를 갖추고, 핵심 기능들이 안정적으로 동작하도록 만들어야 한다. 다음 주는 바로 이 부분에 더욱 더 집중할 예정이다.
세 번째 목표는 철저한 테스트 준비다. 작동하지 않는 부분이나 서버가 터지는 문제에 대한 두려움은 당연히 존재한다. 하지만 문제를 회피하기보다 이에 대응할 수 있는 체계를 구축하는 것이 중요하다고 생각한다. 이벤트 로깅이나, 오류 모니터링 시스템을 체계적으로 구축해서 어디서 문제가 생겼는지 파악할 수 있도록 준비할 것이다.
네 번째 목표는 냉철하게 분석하고 개선하는 과정이다. 테스트 후 단순히 “고생했다”로 끝내는 것이 아니라, 문제 발생의 원인들을 꼼꼼하게 파악하고, 부족했던 부분들을 솔직하게 짚어보려고 한다. 우리 팀은 매주 팀 회고에서도 솔직하게 의견을 나누고 있는데, 이번 오픈 스테이지 이후에도 회고를 진행하며 개선해나가고자 한다.
열정만으론 부족하다.
프로젝트에 대한 열정만큼은 누구보다 크다고 자신한다. 하지만 현실은 냉정하다. 열정은 저절로 드러나지 않고, 결과로 증명될 때나 비로소 의미를 갖는다. 그저 “열심히 했어요”로 끝나면 아무것도 변하지 않는다. 남은 기간 동안은 우리의 노력이 구체적인 성과로 드러날 수 있도록 집중할 것이다.
깨지더라도 부딪히고, 배우고, 개선하면서 앞으로 나아갈 것이다. 이번 오픈 스테이지를 통해 서비스 단계에서 부족한 점이 무엇이 있을지 마주하고자 한다.
소켓 복구 전략
어떤 목표가 있었는가?
실시간 화상 강의 서비스의 핵심은 강의자의 영상/음성, 수강생의 제스처가 지연 없이 상호작용하는 것이다. 화상 강의 특성상 네트워크가 끊기거나 느려지는 경험이 강의의 몰입감을 완전히 깨버린다. 따라서 소켓의 안정적인 복구와 실시간성을 확보하는 것이 이번 주 핵심 목표였다.
단순 이벤트 송수신을 넘어, 양방향 미디어 환경을 안정적으로 제어할 수 있는 구조를 직접 설계해보고자 했다.
소켓 옵션을 직접 고민하게 된 배경
이전 프로젝트들에서는 누군가 올려둔 Socket.io 설정을 그대로 가져다 사용했다. 하지만 이번 화상 강의는 네트워크 지연이 곧 사용자 경험의 품질을 결정한다고 판단했다. 각 옵션 수치 하나하나가 사용자 경험에 직결되므로, 네트워크 특성, 사용자 경험, 서버 부하를 모두 고려해 직접 설계하기로 했다.
/** 소켓 연결 타임아웃 시간 (ms) */
const CONNECTION_TIMEOUT = 7000;
/** 소켓 연결 옵션 */
const SOCKET_OPTIONS = {
transports: ['websocket', 'polling'], // 전송방식 우선순위
reconnection: true, // 자동 재연결 활성화
reconnectionDelay: 1000, // 재연결 최소 간격
reconnectionDelayMax: CONNECTION_TIMEOUT, // 재연결 최대 간격
reconnectionAttempts: Infinity, // 무한 재연결
timeout: CONNECTION_TIMEOUT, // 연결 타임아웃
autoConnect: false, // 수동 connect() 호출
}; 소켓 연결 타임아웃은 왜 7초인가?
소켓 연결 요청 시 타이머를 설정해 경쟁시킨다. 타임아웃이 먼저 도달하면 연결 실패 UI를 표시하도록 설계했다.
왜 7초로 설정하게 되었는가?
위와 같은 생각을 하며 7초라는 균형 잡힌 값을 생각하게 되었다. 네트워크의 복구를 충분히 기다려주면서도, 타임아웃 후 "[다시 시도] [강의실 나가기]" 버튼으로 사용자 제어권을 회복시킬 수 있다. 시스템의 대기와 사용자 주권의 균형잡힌 지점이라고 판단했다.
서버의 과부하를 방지하자
reconnection: true // 자동 재연결 활성화
reconnectionDelay: 1000 // 최소 간격 1초
reconnectionDelayMax: 7000 // 최대 간격 7초서버나 네트워크가 일시 끊길 때, 모든 클라이언트가 동시에 재연결 시도하면 서버가 과부하가 발생한다. 최소 1초의 텀을 두어 서버 여유를 주면서도 사용자에게는 빠른 복구감을 주고자 했다.
Socket.io는 재연결 시 지수 백오프 알고리즘을 사용한다. 재시도 간격이 점진적으로 늘어난다.
1초 → 2초 → 4초 → 7초(상한선)상한선을 7초로 제한한 이유는 서버가 이미 복구됐는데도 클라이언트들이 늦게 접속하면 사용자 경험이 떨어지기 때문이다. 따라서, 서버가 정상화 된 후 최대 7초 내 클라이언트 복구가 가능하도록 설정하였다.
무한 재연결과 사용자 제어의 균형
사용자가 탭을 닫지 않는 한, 지하철/엘리베이터 안, 다른 Wi-Fi로의 연결 변경과 같은 일시적인 단절에서도 자동 복구를 시도해야 한다. 따라서 재연결 시도는 무한으로 설정했다.
하지만 무한 대기는 사용자 사용자에게 무력감을 줄 수 있다. 그래서 앞서 설정한 7초 타임아웃 후 UI 전략을 도입하게 되었다.
"연결 중..." (0~7초, 백그라운드에서 재연결 시도)
↓
타임아웃 발생
↓
"[다시 시도] [강의실 나가기]" (백그라운드에서 여전히 재연결 시도)내가 보낸 이벤트가 정말 전달됐을까?
/** 서버에 이벤트 전송 */
socket.emit(event, ...args);단순히 emit을 호출하는 것과 서버가 이를 수신했는지 확인하는 것은 별개의 문제다. 네트워크가 불안정한 순간에 emit을 하면, 클라이언트는 보냈다고 생각하지만 서버는 받지 못하는 상황이 발생한다.
이를 위해 Ack 콜백을 활용하고자 했다.
- 클라이언트 →
socket.emit(event, ..., (ack) => {...}) - 서버가 이벤트 처리 후 응답 전송
- 클라이언트가 응답 확인 후 UI 성공 업데이트
우리 서비스에서는 제스처를 통해 실시간 점수와 순위를 반영된다. 이벤트 누락이 발생하면 사용자가 바로 알아챌 수밖에 없다. 그래서 Ack이 없으면 재전송하거나 실패 알림을 띄우는 방식을 도입해 확정적인 UI 업데이트를 보장하려 했다.
학습하며 부족했던 부분
소켓 모듈에 기능을 하나씩 추가하면서 기능 간 충돌 가능성을 제대로 고려하지 못한 부분이 있었다. 초기에는 개별 기능에 대해서만 고민하다 보니 전체 시스템의 안정성을 놓친 것 같다. 이로 인해 완성도가 부족하다는 느낌을 받았고, 다시 공부해보고 수정해야겠다.
복구 상황에서 서버와 클라이언트의 데이터 동기화 처리를 놓치고 있었다. 네트워크 재연결 시 클라이언트가 최신 상태를 서버로부터 동기화받도록 해야 한다. 타임스탬프를 잘 활용하면 좋을 것 같은데 주말동안 한번 고민해보려 한다.
PR을 상세히 기록하자
목표를 세우게 된 배경
프로젝트 진행을 위하여, 팀 전체의 작업 흐름과 이해도를 높이는 것이 중요하다고 판단했다. 코어타임은 정해져 있고, 각자 기능 구현에 집중해야 하는 환경에서 다른 팀원의 작업 상황을 실시간으로 따라가기는 쉽지 않다. 슬랙이나 스크럼을 통해 공유하는 방식으로는 깊이 이해하기까지 한계가 있었다.
이에 대하여 프로젝트 초반에 팀원들과 논의한 적이 있었다. 결론적으로, PR을 단순한 병합을 위한 과정이 아니라 문서화 도구처럼 활용하기로 했다. 코드 변경사항, 작업 배경과 결정 이유 등, 상세히 기록하여 서로의 작업을 이해할 수 있도록 규칙을 정했다. 이렇게 하면 학습과 개발 속도가 동시에 향상될 것이라 생각했다.
PR을 작성하는 방법이 있다면?
PR 작성 시 가장 신경 쓰는 부분은 고민했던 선택의 이유를 구체적으로 기록하는 것이다. "이렇게 했습니다"가 아니라 "어떤 기준으로 결정했는지"를 자세히 설명하고자 했다. 또한 "이 코드를 사용할 때 이렇게 접근하면 좋다"는 가이드도 함께 남겨 다른 팀원이 나중에 코드를 볼 때 바로 이해할 수 있도록 했다.
기존 구현 방식의 문제점과 개선 배경도 기록했다. "더 나은 방법으로 바꿨다"가 아니라 "어떤 문제가 있었고, 왜 새로운 방식이 더 나은지"를 풀어서 작성한다.

또 다른 규칙은 PR이 승인된 이후에 추가된 수정사항 에 대한 투명성이다. 승인 후, 추가 수정 시에는 코멘트나 슬랙에 변경사항을 남겨 팀원의 혼란을 방지하고자 하였다.

이를 통해 어떤 변화가 생겼는가?
PR을 통해 내 작업을 다시 한번 객관적으로 돌아보게 되었다. 작업 중에는 "이렇게 해야겠지" 하며 빠르게 진행하지만, PR 작성 시에는 "이 결정을 왜 내렸는지, 다른 팀원이 봤을 때 납득할 수 있을지"를 고민하게 되었다. 이 과정에서 단순히 코드만 작성하는 프로젝트가 아니라 의미 있는 작업을 하고 있다는 느낌을 받았다.
다른 팀원의 PR을 볼 때는 코드 리뷰 전에 맥락을 먼저 이해할 수 있어 코드 읽는 시간이 줄어들었다. "이런 상황을 고려해서 이렇게 구현했구나"를 파악하고 들어가니 실제 코드 분석이 훨씬 수월해졌다.
아쉬운 점이 있다면?
가장 큰 문제는 PR 작성에 시간이 많이 걸린다는 점이다. 구현 예상 시간에 PR 작성을 포함하면 15-30분이 추가로 소요된다. 하루에 2-3개 PR을 올리면 계획보다 1-2시간이 늘어나는 셈이다.
이를 해결하기 위해 PR 작성 방식을 조정해볼 생각이다. 모든 내용을 지나치게 상세히 쓰지 않고 핵심만 이해할 수 있을 정도로 남기고자 한다. 트러블슈팅이나 세부 사항은 노션에 기록하고, PR에는 해당 링크만 첨부하는 방식으로 바꿀 것이다. 노션에는 우선 간단히 정리하고, 시간적 여유가 있을 때에 보충하는 식으로 개선해보고자 한다.
회고를 마무리하며
지금까지 과정을 다시 돌아보라.
이번 주 작업을 돌아보니 작업 시간이 길어지고 수정이 반복되는 부분이 눈에 띄었다. 이런 상황에서 이전 학습 스프린트 기간이 떠올랐다. 그때도 비슷한 문제를 겪다가 결국 초반 설계에 투자하는 시간이 부족했음을 깨달았었다.
당시에는 화이트보드에 전체 흐름을 그림으로 정리하는 방식으로 해결했다. 머릿속 생각들을 시각적으로 옮기고 나서야 개발에 들어갔는데, 전체 틀이 잡히면서 어떤 부분에 어떤 로직이 들어가야 하는지가 명확해졌다. 이를 통해서 코드 수정 횟수가 줄고 실제 개발 속도도 빨라진 경험이 있었다.
반면 이번 프로젝트에서는 화이트보드를 활용하는 횟수가 확실히 줄었다. 기능 구현에 바로 뛰어들다 보니 중간중간 방향을 재조정하느라 시간도 많이 허비했다. "또 무작정 코드를 쓰고 있진 않은가"라는 생각도 들 정도로 설계 단계를 넘긴 부분이 있었다.
다음 주에는 설계에 다시 힘을 싣고자 한다. 머릿속에만 있는 생각을 화이트보드에 옮겨 점검한 뒤 개발에 들어갈 것이다. 초반 30분 정도의 설계 투자로 나중에 몇 시간씩 절약할 수 있을 것이라 생각한다.
더 나아가서
다음 주의 가장 중요한 사안은 오픈 스테이지를 성공적으로 마무리할 수 있도록 준비하는 것이다. 이런 대규모 실시간 테스트 환경을 경험할 기회는 흔치 않으며, 솔직한 피드백을 직접 받을 수 있는 기회라고 생각한다.
이번 오픈 스테이지는 단순한 이벤트가 아니라 서비스 완성도를 검증받는 터닝포인트가 될 것이다. 어떤 내용들을 준비해야 할지 미리 논의하고 점검해야 한다. 철저한 준비를 통해 안정적이고 가치 있는 테스트가 되었으면 좋겠다.
![[네이버부스트캠프 웹・모바일 10기] 멤버십 20주차 회고](/_next/image?url=https%3A%2F%2Fblush-tv-2cc.notion.site%2Fimage%2Fhttps%253A%252F%252Fprod-files-secure.s3.us-west-2.amazonaws.com%252F98c56d22-9c7a-4813-8d64-5f204cf1f90b%252F2da3911d-2991-46cc-b4f7-87da79d1ca2d%252F%2525E1%252584%252589%2525E1%252585%2525B3%2525E1%252584%25258F%2525E1%252585%2525B3%2525E1%252584%252585%2525E1%252585%2525B5%2525E1%252586%2525AB%2525E1%252584%252589%2525E1%252585%2525A3%2525E1%252586%2525BA_2022-08-11_%2525E1%252584%25258B%2525E1%252585%2525A9%2525E1%252584%252592%2525E1%252585%2525AE_3.42.31.webp%3Ftable%3Dblock%26id%3D2f3c8de2-0bcb-8025-acac-ec56789dc498%26cache%3Dv2&w=3840&q=75)
![[네이버부스트캠프 웹・모바일 10기] 멤버십 18주차 회고](/_next/image?url=https%3A%2F%2Fblush-tv-2cc.notion.site%2Fimage%2Fhttps%253A%252F%252Fprod-files-secure.s3.us-west-2.amazonaws.com%252F98c56d22-9c7a-4813-8d64-5f204cf1f90b%252F74372224-b2d1-4a2e-b070-df3c69724f6f%252F%2525E1%252584%252589%2525E1%252585%2525B3%2525E1%252584%25258F%2525E1%252585%2525B3%2525E1%252584%252585%2525E1%252585%2525B5%2525E1%252586%2525AB%2525E1%252584%252589%2525E1%252585%2525A3%2525E1%252586%2525BA_2022-08-11_%2525E1%252584%25258B%2525E1%252585%2525A9%2525E1%252584%252592%2525E1%252585%2525AE_3.42.31.webp%3Ftable%3Dblock%26id%3D2e3c8de2-0bcb-8079-a415-fdffce31e8cc%26cache%3Dv2&w=3840&q=75)
