Connectrip
- 기간: 2024.08 ~ 2024.10 (2개월)
- 개요: 동행 내 실시간 채팅과 위치 공유를 지원하는 국내 여행 커뮤니티 서비스
- Github-1: https://github.com/100-hours-a-week/5-team-ark-connectrip-fe
- Github-2: https://github.com/100-hours-a-week/5-team-ark-connectrip-be
- disquiet: https://disquiet.io/product/connectrip
Connectrip은 국내 여행 동행자들을 위한 실시간 채팅과 위치 공유 서비스다. 2개월 동안 5명의 팀원과 함께 개발하면서 처음으로 팀장 역할을 맡았다.
서비스는 동행자 모집 게시물 작성, 실시간 채팅, 여행 일정 공유 기능을 제공했다. 특히 동행 중 실시간으로 위치를 공유하고 대화할 수 있도록 하는 것이 핵심 기능이었다.
솔직히 말하면 처음엔 팀장이라는 게 단순히 일정 관리나 회의 진행 정도라고 생각했다. 하지만 실제로는 전혀 달랐다.
프로젝트 기획 단계에서 팀원들 간 의견 충돌이 발생했다. 주요 논점은 구현 가능성에 대한 우려와 기능 우선순위의 차이였다. 이로 인해 약 5일의 일정 지연이 발생했고, 작업 속도 저하와 팀 내 긴장감 증가로 이어졌다.
원인을 분석해보니 API 명세가 엉성했다. 백엔드 API는 계속 바뀌는데 명세는 업데이트가 안 돼서 서로 다른 걸 만들고 있는 상황이 반복됐다.
매일 정기 회의 외에 팀원들과 1:1로 만나서 이야기해보니, 다들 API 명세가 문제라는 걸 알고 있었지만 어떻게 해결해야 할지 막막해했다.
그래서 Notion에 API 명세부터 쓰고 개발하자고 제안했다. 엔드포인트, 요청/응답, 에러 코드를 미리 정의하고 팀원들이 검토한 다음에 개발을 시작하는 방식으로 바꿨다. 나중에는 Swagger로도 문서화해서 "API 먼저 쓰고 개발"을 팀의 룰로 정착시켰다.
결과적으로 API 개발 기준, 개발 속도가 40% 정도 빨라졌고, 초기 12개 API 목표였는데 17개까지 만들 수 있었다. 무엇보다 팀원들 간 소통이 원활해지면서 분위기도 많이 좋아졌다.
초기에는 AWS t2.micro 인스턴스 사용으로 메모리 부족 문제가 있었다. 스왑 메모리 설정으로 가용 메모리를 확장하고, Docker로 Nginx와 Spring 애플리케이션을 컨테이너화했다. Docker Compose를 사용해 서비스 구성 요소를 정의하고, 배포 과정을 간소화했다.
처음엔 단순한 EC2 인스턴스 하나에 모든 걸 올렸는데, 서비스 안정성을 위해 아키텍처를 개선했다. ALB와 2개의 EC2로 프론트엔드와 백엔드 서버를 분리 운영하고, 각 EC2에서는 Nginx와 Docker를 활용한 유사 블루/그린 배포 방식을 적용했다. 배포 시 서버 컨테이너를 순차적으로 교체하여 다운타임을 최소화했다.
1개월 2주 만에 MVP를 출시하고 Disquiet에서 첫 서비스 홍보를 진행했다. 처음 외부에 서비스를 공개하는 것이라 긴장됐지만, 여러 관심과 피드백을 받을 수 있었다.
이후 서비스를 더욱 완성도 높게 만들기 위해 채팅 기능을 추가 개발했다. 데이터베이스는 기존 AWS RDS(MariaDB)에 더해 채팅과 캐싱 기능을 위해 EC2에 MongoDB와 Redis를 구축했다. 당시엔 비용 절약을 위해 이렇게 구성했지만, 지금이라면 DocumentDB나 ElastiCache for Redis 같은 관리형 서비스를 사용했을 것이다.
채팅 기능 구현이 처음이라 레퍼런스를 찾아보니 MongoDB를 많이 사용하고 있어서 도입했다. 아마 하나의 문서에서 메시지들을 쌓는 방식 때문에 많은 글에서 MongoDB를 사용한 것 같았다. 실제 구현에서는 채팅 Room과 Message 엔티티를 분리해서 구성했다. 돌이켜 생각해보면 이 방법은 MongoDB의 장점을 살리지 못하고 복잡도만 늘린 것 같다. 이런 구조라면 소규모 서비스라 RDB로 해도 문제없지 않았을까 싶다.
채팅 기능까지 완성한 후 Disquiet에서 두 번째 홍보를 진행했다.
운영 중에는 예상치 못한 문제들도 겪었다. 배포 설정 오류와 코드 로직 문제로 서버가 다운되는 일이 발생했다. 급하게 서버를 재시작했지만 모니터링 시스템이 없어서 문제 파악에 시간이 오래 걸렸다. 이 경험을 통해 서비스 운영이 단순히 개발만으로 끝나는 게 아니라는 걸 몸소 느꼈다.
가장 인상적이었던 피드백은 "로그인한 사용자만 서비스를 사용할 수 있어서 어떤 서비스인지 알기 어렵다"는 의견이었다. 개발자 관점에서는 당연하다고 생각했던 부분이 사용자에게는 진입 장벽이 되고 있었다. 어떻게 개선할지에 대한 것을 마일스톤에 추가했고, 임시로 로그인 페이지에 서비스 소개 이미지를 넣어 해결했다.
제한된 예산으로 최소한의 구성이었지만 나름 안정적으로 서비스를 운영할 수 있었다. Docker와 AWS 서비스들을 조합해서 다운타임을 최소화 할 수 있는 배포 방법을 터득했다.
동행 게시물 생성 API에서 같은 테이블을 여러 번 조회하는 문제를 발견했다. 성능 개선 전후를 비교하기 위해 간단한 부하 테스트를 진행했다.
테스트 환경은 t2.small 인스턴스에서 plow 도구를 사용했다. 총 500개 요청을 동시 연결 수 50으로 설정해서 진행했다.
로직 수정 후 총 처리 시간은 22.6% 단축, 평균 RPS는 30.6% 향상, 평균 대기 시간도 22.3%로 개선됐다.
아쉬웠던 점은 시간이 부족해서 충분한 테스트를 진행하지 못했다는 것이다. 다양한 시나리오나 다른 API들과의 연동 테스트까지 해보고 싶었지만 일정상 어려웠다.
팀을 이끄는 법과 제한된 자원으로 목표를 달성하는 법을 배웠다. 실제로 운영하는 서비스를 만들어내고 팀을 하나로 모았다.
이를 통해 내가 진짜 원하는 것이 무엇인지 고민하게 됐다. 코드를 작성하는 것인가, 제품을 만드는 것인가. AI가 빠르게 발전하는 지금, 단순한 코딩은 언젠가 대체될 수 있다.
그렇다면 어떤 가치를 제공해야 할까. 좋은 제품이 뭔지 정의할 수 있어야 하고, 사용자가 실제로 원하는 걸 만들 수 있어야 한다. 빠르게 출시해서 피드백 받고 개선하는 사이클을 돌릴 수 있어야 하고, 그 과정에서 팀과 잘 협업할 수 있어야 한다. 결국 기술적 구현 능력보다는 제품을 만드는 전체 과정을 이해하고 이끌어가는 능력이 더 중요해질 것 같다.
팀장 역할이 익숙하지 않았는데 다들 잘 따라와 줘서 무사히 끝낼 수 있었어. 서로 끌어주며 함께한 시간들이 정말 소중했어. 2개월이라는 시간이 길다면 길고 짧으면 짧았지만 절대 잊지 않을 거야.
못난 팀장 만나 고생시켜서 미안해, 이 글 보면 연락줘 커피 사줄게, 모두 고마워.