[디프만] 13기 서버 후기

손시연·2023년 10월 2일
18

depromeet

목록 보기
4/5
post-thumbnail

디프만 지원 계기를 짧게 요약하자면, 직장인 개발자와 팀원으로 만나는 것이 매력적이었기 때문이다. 길게 요약한 건 여기에 정리해 두었다.

📆일정

4월부터 7월까지 매주 토요일 14~17시까지 정규세션이 진행된다.

🎓학업 병행

우리 팀은 매주 2번의 서버 회의, 1번의 팀 전체 회의, 토요일 정규 회의까지 총 4번 회의를 진행했다.
학교를 병행하며 개발과 회의에 참석하자니 일정이 빡빡했다. 학교 봄 축제 시즌에도 서버 회의에 참석할 정도였다. 프로젝트에만 집중하고 싶다면 휴학을 추천하지만, 매일 갓생처럼 살 수 있다면 병행해도 가능할 것이라 생각한다!

👩‍🏫기획

💁‍♂️아이디어

생각보다 기획에 많은 시간이 소요되지 않았다. 4월 아이디에이션 회의에서 바로 아이디어를 확정짓고, 꾸준히 발전시켜 나가고 있다.

선정된 아이디어는 "사용자 위치 기반 음악 공유 소셜 서비스" 이고, 이름은 "스트릿드랍" 이다.
기존의 스트리밍 서비스는 음악 데이터를 리스트 형식으로 시간 순으로 쌓는 것이라 생각했다. 그러나 스트릿드랍은 공간 데이터에 음악 데이터를 쌓는 컨셉을 가진다.

💁‍♀️설문 조사

링크: https://forms.gle/2wCZMwSof9t9cXCVA
(기존 설문 조사는 종료 되었고, 샘플 사본을 생성하였다)

잠재적 사용자의 행동 패턴과 니즈를 파악하기 위해 음악 스트리밍 서비스를 자주 이용하는 사람들을 대상으로 설문조사를 진행했다. 총 응답자 수는 201명이었고, 기간은 2023.04.12 ~ 2023.04.19 이다.

설문 결과, 응답자 중 대다수가 바깥 활동 중️에 유튜브 뮤직으로 음악을 자주 듣는 편이고, 장소와 상황에 따라 듣는 음악에 차이가 존재함을 알 수 있었다.

📱UT

링크: https://t.maze.co/162661444

6주차 때 UT(User Test, 사용성 테스트)를 진행했다. UT를 통해 새로운 기능이나 서비스를 런칭하기 전 사용자의 반응을 살피고 가설을 미리 검증할 수 있다.

Maze로 진행했고, 주요 기능 위주로 미션을 구성했다.
피그마 이미지 용량 문제로 모바일로 접근하면 무한 로딩 문제가 발생한다. 컴퓨터로 접근하는 것을 추천한다.


UT를 진행하며 UX의 중요성을 크게 느꼈다. 본인은 서버 개발자이지만, 다른 팀의 UT에 참여하며 좋은 점과 개선 점을 고민하는 과정에서 UX의 중요성을 깨달았다. 사용자 경험이 일정 수준 보장되어 있어야 유저 리텐션을 높일 수 있겠다고 느꼈다.

UT는 처음 경험해 보지만, 제대로 된 프로젝트에서는 필수라고 느꼈다. A/B 테스트와 더불어 새로운 기능이 제품에 반영되기 전에 꼭 진행해 보면 좋을 것 같다!

👩‍💻서버 개발

백엔드 깃허브: https://github.com/depromeet/street-drop-server

🎤저작권 문제

개발자답게 기획 회의 후 개발을 시작하기 앞서 기술 난이도 확인하고 실현 가능성을 고려했다.

음악 재생과 관련해서 '앱 내에서 재생하기' vs '음악 스트리밍 앱으로 위임하기' 중 쉽게 정하지 못했다.

전자는 매우 매력적인 기능이었다.
서비스의 컨셉이 '길을 걸으며 음악을 추천하는 서비스' 이기 때문이다. 스트릿드랍 앱 안에서 다른 사람이 추천한 음악을 바로 들어볼 수 있다면, 사용자 경험 측면에서 좋을 것이다. 다른 음악 앱으로 넘어갈 때 어쩔 수 없이 스트릿드랍 앱 밖으로 나가버리는 것은 치명적인 문제라고 생각했다.

그러나 음악 저작권 문제로 인해 후자를 선택하게 되었다. Apple 앱 심사에서 저작권 문제로 리젝을 당할 것을 고려 했을 때, 기획 단계에서 안정적인 것을 선택해야 했다.
또 사이드 프로젝트를 넘어서 수익화를 생각했을 때, 음악 실행을 음악 스트리밍 서비스로 위임하는 것이 적합하다고 판단했다.

🎹음악 데이터베이스 구축

약 9천만곡 가까이 되는 음악 데이터 베이스를 어떻게 구축할까?
음악 데이터베이스 구축하면서 MVP를 빠르게 개발하기 위해, 크롤링보다는 외부 음악 API를 활용했다.

음악 검색 API와 관련해서 스포티파이, 애플뮤직, 유튜브뮤직 등을 조사했고, Apple Music 음악 검색 API를 활용하기로 결정했다!

앱 출시를 위해 공용 개발자 계정을 구매할 예정이었고, 프론트엔드 측에서 음악 검색 API를 호출할 예정이었기 때문이다. 별도의 스포티파이나 유튜브 계정 생성 없이 현재 가진 계정을 최대한 활용하자는 취지였다.

🤚검색 서버 분리

  1. 토큰 별 유량 제한 문제
    예를 들어, Apple Music API 요청을 위한 토큰에 1만 명의 사용자가 몰렸다고 생각해보자. 한 토큰에 많은 요청을 보내는 것은 위험하다. 토큰을 여러 개 만들고, 유량 제한을 해야 한다고 생각했다.

    따라서 프론트엔드 측에서 Apple Music API 요청을 보내는 것이 아니라, 백엔드의 검색 서버에서 관리하기로 결정했다. 프론트엔드 → 검색 서버 → Apple Music API의 흐름으로 요청을 보낸다.

  2. 동시 접속자 수로 인한 속도 문제
    음악 검색 API를 외부에 위임하면서 성능 테스를 진행했다. 그 결과 동시 접속자가 30명이 이상될 때, 응답 시간이 1000ms 이상 지연 문제 발생했다.

  3. 검색 서버는 네트워크 I/O가 주된 지연점
    검색 서버는 Apple Music API 요청 보내고, 응답하는 역할만 하면 된다. 즉 별도의 동작 없이 네트워크 I/O만 수행한다.

따라서 API 서버와 검색 서버를 분리하여 안정적인 서버를 구축했다.

🧭위치기반

사용자의 위치 정보를 올바르고 안전하게 저장하기 위해 어떻게 해야할까?

MySQL 8.0부터 공간 데이터 타입을 지원하기 시작했다. 스트릿드랍에서는 사용자 위치를 저장하는데 Point 타입을 활용했다.

다만, Point 타입은 좌표 기반 검색에서 다소 미흡하다고 느꼈다. PostgreSQL의 PostgreGIS이 공간 데이터 처리에 더 적합하다는 것을 알게 되었다. 현재는 PostgreSQL의 도입과 데이터베이스 이전을 고려하고 있다.

🏘️멀티 모듈

아키텍처 설계 초반에 멀티 모듈, 헥사고날 아키텍처, MSA에 대해 이야기가 나온 적이 있다. 토이 프로젝트 수준에서는 오히려 오버엔지니어링이 될 수 있다고 판단했고, 적용하지 않기로 결론냈다. 덕분에 비즈니스 로직과 기능에 더 집중할 수 있었다.

그러다 기능들이 계속 추가되었고, 어드민 서버와 음악 검색 서버의 별도 운영이 필요했다. 새로운 레포지토리를 통해 관리하고자 하니, 프로젝트 레포지토리를 여러 군데 사용하기 번거로웠다.

결국 초반에 언급되었던 멀티 모듈과 MSA에 대해 고민하기 시작했다.

모놀리식 아키텍처는 단일 코드 베이스로 관리한다. 이로 인해 개발과 유지 보수가 복잡해지고 기능 간 강한 결합을 형성한다. 그러나 서비스 단위로 모듈화하면, 모듈 간 높은 응집도와 낮은 결합도를 형성할 수 있다.

이러한 이유로 스트릿드랍에도 멀티 모듈을 적용했다. 현재 구조는 다음과 같다.

🎨아키텍처

이전 프로젝트에서는 객체 지향, 클린 코드, 코드 리뷰에 중점을 두었다. 개발자로서 갖추어야 할 가장 기본적인 요소라 생각했기 때문이다. 또 기본부터 탄탄하게 시작해야 유지 보수에도 유리할 것이라 생각했다.

이번에는 오히려 코드를 짜는 시간보다, 설계하는 시간이 더 길었다. 멀티모듈 구성과 함께 아키텍처에 대한 고민을 시작했다. 안정적인 서버 운영과 서비스 확장성이 가장 주된 이유였다. 코드 재사용성과 유지보수 용이성을 위해 모듈화하고, 안정적인 운영을 위해 서버를 분리하였다.

아키텍처를 수정할 때마다 팀원들과 몇 시간씩 회의를 진행했다. 이전 구조의 문제는 무엇이며, 변경된 구조의 장단점은 무엇인지 깊이 고민하고 결정했다.

그렇게 스트릿드랍 백엔드 아키텍처는 다음과 같다. 단계마다 부연 설명을 작성하기에는 글이 길어질 것 같아서 다른 글에서 멀티 모듈과 아키텍처 변화 과정에 대해 작성해 보겠다.

  1. 프로젝트 시작할 때
  1. 검색 서버 분리
  1. 어드민 서버 분리
  1. 디프만 종료 직후
  1. 현재 아키텍처
  1. 미래의 아키텍처

한 달만 지나도 또 변경될 것 같다. ‘No Silver Bullet’ 이 크게 와닿았다. 문제 해결을 위한 완벽한 정답은 없다. 어떻게 설계해야 모듈 간 의존 관계를 줄이고, 결합도를 낮출 수 있을지는 여전히 고민이다.

💰AWS 비용

현재 아키텍처를 갖추게 된 이유는 AWS 비용 문제가 크다.

필요한 EC2들을 모두 나열해보자면 다음과 같다.

  1. 검색 서버
  2. 어드민 서버
  3. 운영용 API 서버
  4. 개발용 API 서버
  5. 알림 서버
  6. 배치 서버
  7. 기타 테스트용 서버(CD 테스트, 부하 테스트, ELK 등)

디프만에서 서버비를 지원했을 때는 마음껏 사용할 수 있었다. 그러나 디프만 종료 후 서버비 지원이 사라지면서, 금액을 모두 팀에서 담당해야 했다.

그렇게 디프만 종료 후, 첫 달에 청구된 서버비는 18만 9천원이었다.

비용 문제로 현재와 같은 아키텍처를 갖추게 되었고, 일부를 홈 서버에서 운영하고 있다.

💁‍♂️어드민 페이지

사이드 프로젝트를 하며 "프론트엔드 개발자나 디자이너가 어떻게 데이터를 볼 수 있을까?"에 대한 고민을 한 적 있다. 수정하거나 삭제하고 싶은 데이터가 있을 때마다, 백엔드 개발자가 직접 데이터를 변경했다. 또 서비스에 누적된 데이터를 한 눈에 시각화할 있는 페이지가 있었으면 좋겠다고 생각했다.

어드민 페이지는 이 문제들을 말끔하게 해결했다. 백엔드 개발을 하며 어드민 페이지도 동시에 개발했다. 백엔드 개발자가 아니더라도 권한이 있다면 데이터를 직접 열람/수정하고 통계 지표도 볼 수 있다.

또 단순히 유저를 많이 모으는 것을 넘어서 유저 리텐션 지표를 분석했다. 이로 인해 개발보다는 기획에 대한 고민도 많아졌다. 유저의 시선에서 서비스를 되돌아 보고, 서비스를 개선하는 과정이 필요했다. 이를 계기로 개발과 더불어 QA에 많은 시간을 투자하기 시작했다.

👀모니터링

어드민 페이지를 통해 모니터링의 중요성을 알게 되었다. 쿼리 최적화 등 성능에도 도움이 되었고, 운영 서버의 장애에 즉각적으로 대응할 수 있었다.

  1. 슬로우 쿼리 모니터링
    RDS에서 Cloud Watch와 Lambda를 통해서 슬로우 쿼리 모니터링을 구성했다. 실행시간이 1초 이상되는 쿼리들을 슬랙으로 알림을 받고 있다.

  2. 서버 상태 모니터링
    프로메테우스랑 그라파나를 통해서, 서버의 CPU와 램 상태를 모니터링 하고 있다.

  3. 500 에러 모니터링
    500번대 에러나 외부 서버에 에러가 발생했을 때 슬랙을 통해서 바로 모니터링 할 수 있다. 또한 서버 상에서 에러 발생 시 로그를 확인하기 위해서 x-amzn-trace-id 값을 비교하여 해당 발생한 문제를 파악하고 빠르게 해결할 수 있다.

  4. ELK
    ELK(Elasticsearch + Logstash + Kibana)는 로그 데이터를 실시간으로 수집하고 저장하여, 대규모 시스템에서 발생하는 문제를 빠르게 식별하고 해결할 수 있다. 그러나 Elasticsearch의 비용 문제로 중단하게 되었다. ES 자체도 이미 비싸고, EC2에 Docker로 올려도 메모리 소모가 컸기 때문에 무리가 있었다. 추후 입사해서 공부해 보기로 혹은 서버비 지원을 받을 수 있게 된다면 반영하기로 결정했다.


💣최종 발표

최종 발표를 맡게 되었다.

발표 영상: https://youtu.be/GiSKOQHeht0

애정이 가는 프로젝트들은 항상 PM을 맡거나 프로젝트 최종 발표를 담당했다. 프로젝트에서 많은 의견을 낼 수 있고 주체적으로 참여할 수 있을 때, 폭발적으로 성장할 수 있었기 때문이다.

사실 스트릿드랍에서 최종 발표를 하는 것은 프로젝트 중반부터 점점 욕심이 들었다. 아이디네이션부터 성공할 것 같은 믿음이 있었기 때문이다


📚스터디

자유롭게 스터디를 생성하고, 팀원들을 모아 자유롭게 스터디를 진행한다.
그 중 2개 스터디를 참여했는데, 낙오자 없이 모두가 열정적이라 인상적이었다.

♻️알고리즘 스터디

매주 2문제씩 해결한다. 처음에는 고작 2문제라며 자신만만했다. 막상 학교 + 디프만 프로젝트 + 알고리즘 스터디까지 병행하느라 힘들었다.

프로젝트를 진행하다 보면 알고리즘 공부에 등한시하게 되었는데, 꾸준한 습관 형성에 도움이 되었다. 또 디프만 활동하다 보면 다른 팀 사람들과 친해질 구실이 없었는데, 다른 팀의 다른 파트 개발자들과 친해질 수 있었던 좋은 경험이었다.

♻️Effective JAVA 3/E 스터디

스터디 레포지토리: https://github.com/depromeet/effective-java-study

디프만에서 시작해서 끝나고도 2달 더 이어왔던 스터디이다. 이전부터 읽고 싶었던 Effective JAVA 3/E을 팀원들과 토론하며 읽을 수 있어서 좋았다.

코드를 작성할 때 아무 이유 없이 '남들이 쓰니깐' 개발했던 습관들에 올바른 이유를 찾은 기분이다. 예를 들어 private 필드를 생성하고, public 메서드를 통해서만 데이터 접근하는 이유(관련 글), static 메소드 이름으로 from이나 of를 사용하는 이유(관련 글) 등이 있었다.


🏭디프만이 끝나고

디프만이 끝나고 프로젝트를 계속 이어나가기로 했다. 작은 프로젝트 여러 개 하는 것보다 완성도 있는 프로젝트 하나를 만들고 싶었기 때문이다. 여전히 성능적으로 기술적으로 기능적으로 도전하고 싶은 요소들이 많기 때문이다.

지금은 매주 2번의 서버 회의와 1번의 전체 회의를 하며 프로젝트를 디벨롭하고 있다. 디프만 종료와 함께 AWS/NCP 지원이 사라진다. 이제 서버비가 많이 나올 수록 전적으로 팀에서 부담해야 하기 때문에, 비즈니스 모델의 중요성에 대해 크게 깨닫고 있다.


✍️한 줄 요약

배울 점이 많은 팀원들과 재미있는 프로젝트를 하게 된 소중한 기억이었기 때문에, 디프만 활동을 고민하고 있다면 강력하게 추천한다!

profile
Server Engineer

5개의 댓글

comment-user-thumbnail
2023년 10월 4일

안녕하세요? 인상적인 글 잘 보았어요! 멋진 개발자가 되실 것 같아요! 앞으로도 기대하겠습니다 =)

1개의 답글
comment-user-thumbnail
2023년 10월 9일

앱 완성도가 높아서 정말 놀랐었어요 💙 멋져요 잘 읽고 갑니다!

1개의 답글
comment-user-thumbnail
2023년 10월 15일

엄청난 경험인 것 같네요. 멀티모듈이나 아키텍처 설계에서 이해도가 필요할 것 같은데 대단하십니다.

답글 달기