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

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

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

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

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

이 규칙들 덕분에 내 작업을 객관적으로 돌아보게 되었다. 작업 중에는 빠르게 진행하더라도, PR을 쓸 때는 이 결정을 왜 내렸는지, 다른 팀원이 납득할 수 있을지를 고민하게 됐다. 반대로 다른 팀원의 PR을 볼 때는 맥락을 먼저 이해하고 들어가니 코드 읽는 시간이 줄고 분석도 훨씬 수월해졌다.
가장 큰 문제는 PR 작성에 시간이 많이 걸린다는 점이다. PR 하나에 15~30분이 추가로 들어, 하루에 2~3개를 올리면 계획보다 1~2시간이 늘어난다. 그래서 PR 작성 방식을 조정해볼 생각이다. 모든 내용을 지나치게 상세히 쓰지 않고 핵심만 이해할 수 있을 정도로 남기고, 트러블슈팅이나 세부 사항은 노션에 기록해 PR에는 링크만 첨부하는 방식으로 바꿀 것이다. 노션에는 우선 간단히 정리하고 시간적 여유가 있을 때 보충하는 식으로 개선해보려 한다.
정리하며
이번 주를 돌아보니 작업 시간이 길어지고 수정이 반복되는 부분이 눈에 띄었다. 이전 학습 스프린트 때도 비슷한 문제를 겪었고, 원인은 초반 설계에 투자한 시간이 부족했던 데 있었다. 당시에는 화이트보드에 전체 흐름을 그려 머릿속 생각을 옮긴 뒤 개발에 들어갔다. 어떤 부분에 어떤 로직이 들어갈지 명확해지면서 수정 횟수는 줄고 개발 속도는 빨라졌다.
이번 프로젝트에서는 화이트보드를 꺼내는 횟수가 확실히 줄었다. 기능 구현에 바로 뛰어들다 보니 중간중간 방향을 재조정하느라 시간을 허비했고, 무작정 코드부터 쓰고 있진 않은가 싶을 만큼 설계 단계를 건너뛴 부분이 있었다. 다음 주에는 머릿속 생각을 화이트보드에 옮겨 점검한 뒤 개발에 들어갈 것이다. 초반 30분의 설계 투자가 나중의 몇 시간을 아껴줄 것이라 생각한다.
다음 주의 가장 중요한 사안은 오픈 스테이지 준비다. 대규모 실시간 테스트 환경에서 솔직한 피드백을 직접 받을 기회는 흔치 않다. 이번 오픈 스테이지는 단순한 이벤트가 아니라 서비스 완성도를 검증받는 터닝포인트가 될 것이다. 무엇을 준비할지 미리 논의하고 점검해, 안정적이고 가치 있는 테스트로 만들고 싶다.