4학년 1학기가 끝날 무렵 본격적으로 개발 경험을 쌓고 싶다는 생각을 하던 차에 학교에서 지원해주는 단기 PBL 프로그램을 알게 되어 좋은 기회다 싶어 지원하게 되었습니다. 2023.06.26 ~ 2023.07.07 2주라는 짧은 기간 동안 진행되었던 프로그램이지만 굉장히 많은 고민을 했었고 저에게 상당한 변화를 주었던 시간이었던 만큼 회고를 진행하고자 합니다.
이번 PBL 프로그램의 경우 사전에 개인 별로 역량 진단 설문조사를 진행해 다양한 사람들끼리 팀을 이루게끔 설정되어 있었습니다. 그런데 어쩌다보니 1, 2학년 친구들과 전과생 친구들로 구성된 팀의 팀장이 되어버렸습니다. 평소 팀에서 적극적인 의견 표현으로 팀을 서포팅을 하는 저로서는 정말 당황스러웠습니다만... 이 또한 경험이란 생각에 오히려 투지를 불태웠습니다.(물론 이후에 정말 힘든 순간이 많았습니다.)
미션으로 주어진 서비스의 구조
해당 프로그램 동안 구현해야 했던 전체 서비스의 구조를 나타낸 이미지입니다. 전체 서비스는 광고 서비스를 MSA 형태로 나누어 설계해놓았습니다. 이에 따라 각 컴포넌트는 다음과 같은 기능을 담당합니다.
App
: 광고 서비스의 대상이 되는 유저가 이용하는 클라이언트 프로그램AD Server
: 게제용 광고 담긴 DB에서 광고를 가져와 유저에게 보여주는 역할을 하는 서버DB
: 게제할 광고와 분석용 로그 정보가 담긴 DBFraud Detection Server
: 광고 서비스를 운영하면서 발생할 수 있는 어뷰징을 탐지하는 서버Global AD Manager Platform server
: 광고와 관련된 관리 기능을 수행할 수 있는 플랫폼 서버2주라는 시간 동안 최대한 해당 구조에 나타난 모든 컴포넌트에 대한 MVP를 작성하는 것이 이 프로그램의 목표였습니다만...
팀에서 실제 구현한 부분
결과적으로는 빨간색 박스에 나타난 부분만 구현하는 것에 성공했습니다...ㅠ
아무래도 시간도 빠듯하고 팀원들에게 많은 CS 및 개발 지식을 공유하는 과정에 많은 시간이 소요되어 다른 컴포넌트 간의 MVP를 작성하는 것은 포기하고 글로벌 매니저 서버와 관련된 MVP만 작성하는 것에 집중했습니다.
사실 어떤 MVP를 목표로 할지 고민할 때, 대부분의 시간을 AD Server
와 App
간의 시퀀스를 완성하는 것을 목표로 데이터 플로우를 생각했지만 실제 개발 전에 프론트 개발 측에서 와이어 프레임이 잘 나타나 있었던 Manager Server 쪽을 선호하여 해당 데이터 플로우에 대한 시퀀스를 집중적으로 개발하기로 결정했습니다.
전체 서비스의 구조를 염두하고 실제 서비스 중인 광고 서비스 1개를 벤치마킹하여 구체적인 시퀀스를 작성하고자 했습니다.
유저를 통해 발생하는 이벤트(액션)를 기반으로 필요한 데이터(파라미터)를 정의하여 각 시퀀스를 완성시키기 위한 최소 단위의 기능 마이크로함수를 작성하는 활동을 진행했는데 4학년 1학기 때, 캡스톤을 진행하면서 비슷한 경험을 했지만 제대로 하려고 하니깐 굉장히 어려웠습니다. 하면서 왜 저희 캡스톤이 망했는지도 느낄 수 있었습니다.
시퀀스의 뼈대를 만들어 컴포넌트 간의 데이터 플로우가 파악된 후에는 컴포넌트를 쪼개 MVC 패턴에 맞춰 시퀀스를 구조를 바꾸었습니다.
개인적으로 이 부분이 첫 1주에서 가장 어려웠던 작업 중 하나였습니다. 일반적인 MVC 패턴을 따라 Controller -> Model -> View
흐름을 따라가게끔 시퀀스를 작성하려고 했지만 해당 내용을 Django에 대입하여 생각하니 controller가 정확히 어느 부분인지 찾지 못 해서 view.py
에 위치시키는게 맞나 의구심이 들어 계속 제자리 걸음을 했습니다.
지나고나서 생각해보니 프레임워크 별로 MVC 패턴을 구현하는 방식이 조금씩 다르니 MVC라는 개념의 큰 틀에서 벗어나지 않게끔 시퀀스를 작성하면 문제가 없다는 걸 뒤늦게 알았습니다.
위에서 생각한 부분들을 아래와 같은 시퀀스로 만들었습니다.
데이터 모델링은 각각 서비스 운영용 DB, 서비스 분석용 DB 2가지를 진행했습니다.
button
, article
etc.)을 같이 테이블의 형태로 만들어 나타내려고 했으나 컴포넌트보다는 이벤트가 훨씬 중요한 지표인 것 같으니 불필요하게 요소들을 기록하지 않아도 될 것 같다는 피드백이 있어 제거한 상태로 모델링을 했습니다.저희는 이 정도 테이블 구조에서 정규화를 진행하기 벅찬데 실제 실무에서는 더 작은 단위로 정규화 및 파편화를 한다는 이야기를 듣고 갈 길이 멀다라는 생각이 들었습니다.
실제로 구축된 인프라
전체 시스템을 구성할 때는 별도의 VPN을 구축했었습니다. 우리 팀 말고 다른 팀들은 로컬 머신에 모든 인프라 요소를 구성하거나 흔히들 쓰는 퍼블릭 클라우드에서 제공하는 인프라 환경을 이용하는 경우도 있었습니다. 저희들도 이와 같은 방법을 이용하려고 했지만 각각 다음과 같은 이유로 선정하지 않았습니다.
🏠 로컬호스트 환경
팀원 각자 자신의 로컬 머신에 가상의 인프라 요소를 구축해서 네트워크를 구성해서 서비스를 테스트 하는 방식으로 가장 단순하게 구축할 수 있다고 판단되었습니다.
다만 이 경우 문제가 되는 것은 실패에 대한 경험을 각자가 다른 방식으로 경험하게 되는 치명적인 문제가 존재합니다.
비슷한 맥락의 다른 예를 들어보죠. 광고에 대해서 CRUD 기능의 REST API 작성한다고 해봅시다. 여기서 단순하게 생각해보면 팀원 4명일 때, 각자 1개씩 맡아서 각자 개발하면 빠를 것이라고 생각할 겁니다.
하지만 이 API에는 Web Application Server <-> Database
양자 간에 커넥션을 맺는 코드가 필요할 겁니다. 문제는 이 부분에서 발생하는데, 각자 팀원 4명이서 Create, Read, Update, Delete API를 각각 맡아서 개발한다고 하면 각자 커넥션 코드를 짤 때 누구는 변수명을 잘못 써서 실패하기도 하고, 어떤 사람은 잘못된 환경변수를 읽어들여 사용해서 실패하기도 합니다. 이처럼 같은 결과(연결 실패)에 대해서 각자 다른 경험(오타, 경로 실수)을 하게 됩니다.
위와 같은 상황을 피하려면 소프트웨어 설계상 Core한 부분(layered architecture 상에서 추상도가 낮은 부분)은 함께 고민해야 합니다. 따라서 구체적인 해법으로는 Pair Programming으로 커넥션을 맺는 부분을 먼저 다같이 구현한 후, 각자 C, R, U, D에서 이 코드를 사용해서 API를 완성해야 할 겁니다. 실제로 저희 팀도 4명이서 같은 화면을 보고 작업한 코드가 있었습니다.
물론 위와 같은 사항에 대해서 각자 실패한 경험을 모여서 공유하면 되지 않나? 생각할 수도 있지만 프로젝트를 단기간에 빠르게 개발해야 하는 상황에서는 다소 취지가 맞지 않다고 생각했습니다.
☁️ 클라우드
클라우드 플랫폼은 이미 많은 요소를 자체 서비스로 제공하고 있기 때문에 합리적인 가격으로 인프라를 안정적으로 구축할 수 있습니다.
다만 저희 팀은 저를 제외하고는 0~1개의 서비스를 써본 경험이 전부였습니다. 따라서 기술 스택의 숙련도를 생각했을 때, 도입하기에 어렵다고 생각했습니다.
사실 교육장의 네트워크 안에서 팀원들의 개인 노트북을 하나의 서버로 만들어 통신하면 끝나는 문제입니다만 현실은 그렇게 쉽지 않더군요.
MySQL DB를 광고 서버와 연결하는 과정에서 연결에 실패하더군요. 처음엔 코드를 잘못 썼나 고민했지만 계속 실패했습니다. 그래서 ping
을 날려보기도 했지만 제대로 응답이 오더군요.
그러다가 문득 네트워크 안에 방화벽이 존재해 특정 패킷을 필터링하는 것 같다는 생각이 들어 모바일 네트워크로 연결된 상태에서 DB 연결을 시도하니 성공하더군요. 그래서 별도의 오버레이 네트워크가 필요하다고 생각되어 VPN을 구축하게 되었습니다. 대학교 네트워크가 떠오르는 현상
와이어 프레임을 참고해서 간신히 AD Maganer Plaform의 기능들을 완성했습니다. 조금 더 시간이 있었으면 다른 부분들도 완성했을 것 같은데 상당히 아쉽다고 느꼈습니다 ㅠ
사실 저는 이번 프로젝트를 하면서 코드를 거의 짜지 않았습니다.
분명 프로젝트를 시작하기 전에는 많은 코드를 짜야겠다고 다짐했었습니다만 실제로는 팀의 의견 조율, 서비스에 필요한 CS지식 공유, 팀원 간 Task 분담 등의 매니저 역할을 했던 것 같습니다.
인생 처음으로 프로젝트의 팀장이 되었던 경험이라 정말 힘들었습니다만 그럼에도 기억에 남거나 깨우친 것들도 많았습니다. 그중에서 이 프로젝트 기간 통틀어서 가장 기억나는 순간이 하나 있었습니다.
아침에 전철을 타고 핸드폰을 보다 온라인 커뮤니티에서 짧은 실시간 인기 글 하나를 보게 되었습니다. 정확한 내용은 기억나지 않지만 다음과 같은 내용이었습니다.
오늘 회사에서 승진 대상자가 정해졌다고 한다. 나와 후보자였던 A, B와의 회의 경험을 생각해보니 A는 나에게 본인의 해결책을 설명하는데 대부분의 시간을 썼고 B는 나와 함께 문제에 대해 고민을 하는데 시간을 썼다.
글은 이렇게 끝나며 누가 승진했는지 적혀 있지 않았습니다만 글의 문맥상 B가 승진했을 것 같아 오늘 하루 한번 B와 같은 사람이 되는 것을 목표로 했습니다.
그날 오후 서비스 분석용 DB를 설계해야 했습니다. 다들 경험이 없어 백지상태의 막막함에 다들 어려워하는 것 같아 제가 생각하는 답을 말하려다 문득 아침의 글이 생각나 조금 다르게 얘기했습니다. 제가 생각한 해법에서 문제 상황에 대한 부분만 떼어내어 예시와 함께 각 팀원들에게 어떤 접근으로 해결할 것인지 물어보았습니다.
유저의 관심은 터치, 스와이프, 클릭, 주시 와 같은 이벤트로 표현될 것 같은데 이걸 어떻게 DB에 녹여낼 수 있을까요? A, B님은 어떻게 하실 것 같은가요? 저는 잘 모르겠네요 ㅠ
유저의 발생시킨 이벤트에 관련된 컴포넌트(광고 슬롯)들은 어느 정도로 생각해야 할까요? 유저가 보고 있는 화면 전부? 아니면 유저와 상호작용하는 컴포넌트? C님은 어떻게 테이블을 설계 시 뭐가 제일 중요해보여요?
위와 같은 질문에 대한 대답은 저도 준비해두었지만 의도적으로 감추고 팀원들에게 물어보고 대답을 듣고 감추었던 제 대답도 말하면서 함께 이야기하니 신기하게도 운영 DB를 설계하는 것보다 빠르게 설계가 끝났습니다.
물론 멘토님께 피드백을 받으면서 저희 팀의 해답에도 개선할 점이 많았습니다만 중요한 건 동작할 수 있는 DB의 설계를 빠르게 뽑아낼 수 있었다는 것입니다. 그리고 팀원들의 사기가 눈에 띄게 올라간 것이 보였습니다.
팀장이라는 것은 정말 별거 아닌 행동으로 많은 것들을 바꿀 수 있는 신묘함을 가진 역할이라는 것을 새삼 느끼게 되었습니다.
배포하지 못 한 temp_pbl 이미지...
사실 제가 코드를 거의 짜지 못했던 이유의 많은 부분을 차지하는 것 같습니다. 전체 프로젝트에 할당된 시간을 봤을 때 분석 및 기획하는데 5일, 프로젝트를 실제로 개발하는데 3일, 발표 2일이었습니다.
실제 개발은 3일 밖에 없었는데 결과적으로 2일을 인프라를 완성하는데 썼습니다. 이유야 많은 것들이 있겠지만 가장 큰 원인은 k8s와 같은 기술에 대한 경험이 없다 보니 수작업으로 인프라를 구성하다 많은 이슈와 시간 지연을 겪었던 것 같습니다.
만약 제가 k8s를 잘 아는 DevOps 엔지니어였다면 리눅스로 통일된 머신 혹은 VM 위에서 동작하는 개발 컨테이너를 만들어 다 같이 그 위에서 개발을 하게끔 통일하고 개발이 끝나면 VPN 상에서 쿠버네티스 클러스터를 구축해서 배포 및 운영을 하게끔 만들면 아주 나이스하게 끝났을 겁니다...
프로젝트가 끝나고 상당한 시간이 지난 지금은 당시의 절망적인 경험 때문에 개인적으로 k8s를 공부하고 있습니다.
돌이켜보면 정말 짧은 시간이었지만 제가 가장 중요하게 생각하는 고민이라는 것에 대해 깊게 생각해본 귀중한 시간이었던 같습니다. 앞으로도 PBL 같은 형태로 학습을 진행하면 개인적인 성장에 큰 도움이 될 것 같습니다.
이런 유용한 정보를 나눠주셔서 감사합니다.