Cali
2024.11.25 ~ 2024.12.24
프로젝트
프로젝트: 캘리
참여 인원: 3 명
디자이너, 프론트엔드, 백엔드
12월의 시작은 크리스마스가 다가온다는 설렘을 같이 안겨주는 달이다. 그러기에 많은 회사에서 마케팅 전략으로 Advent Calendar를 판매하기 시작한다.
크리스마스를 기다리며 하루하루 설렘을 안은 날들을 보내는 것을 기리는 데 이를 소프트웨어화하는 것이 우리 프로젝트의 목표였다.
소프트웨어가 제공할 수 있는 물리적인 것이 없기 때문에 사람들은 특정한 날 기억에 남는 플레이리스트를 만들도록 유도하고 그 플레이리스트는 하나의 앨범처럼 기록되며 이러한 개인화와 커뮤니티성을 제공하고자 한다.
"Good Game Well Played"

"새로운 시작은 내 안에 열정의 불을 지피는 윤활유이다"
자바 플레이그라운드 스터디와 인프라 워크샵 스터디를 진행하면서 강제성을 부여하기 위해 모각코에 참여했다. 그곳에서 만난 귀인 같은 인연을 통해 뜻밖에 사이드 프로젝트에 참여하게 되었다.
너무 좋은 인연과 함께할 수 있다는 생각에 이 프로젝트에 대한 애정이 너무 커졌고 가장 큰 우선순위에 두고 작업했다.
"항상 데이터만 만지던 내가 다시금 API를 만든다니, 마음 맞는 사람과 프로젝트의 같은 결과를 바라볼 수 있다니🥺"
너무 잘 해내고 싶은 마음에 자바를 공부하던 나 자신을 잠시 내려놓고 파이썬으로 돌아왔다.
어렴풋 진행했던 사이드 프로젝트를 둘러보며 환경 구성을 하고 인프라 망 구성을 하고 신나게 아키텍처를 그리는 데 불과 며칠 걸리지 않았던 걸로 기억한다.
머릿속에 정리 되지 않던 AWS 지식들이 손 끝을 통해 하나 둘 씩 자리를 잡아나가고 있었다.

"배포하지 못 한 사이드 프로젝트에서 진주 같은 경험을 얻다"
본격적인 개발 사이클이 시작 되었고 필요한 협의점이 있을 땐 노션으로 정리 해서 문서에 남기거나 온라인 미팅 플랫폼에서 만나거나 오프라인으로 만나면서 정말 시간 가는 줄 모르게 개발이 진행 되었다.
그렇게 API 개발에 속도가 붙고 어느정도 정리가 되어가고 있을 때 "백엔드라면 이정도는 해줘야 돼" 라고 생각 할 몇 가지의 문제들을 마주했다.
유튜브 API 할당량 제한 시 어떻게 유튜브 검색을 제공하지?
운영 환경의 모니터링 지표는 어떤걸 수집하지?
내부망에 있는 RDS를 어떻게 GUI로 접근 해야하지?
국내 IP만 허용 하다보니 GeoIP 메타데이터를 변환할 때 서버가 못 버티는데 어떡하지?
그 외 서버가 마주할 수 있는 몇 가지의 문제들이 더 있었지만 대체적으로 쉽게 해결 되었다.
"유튜브 API 할당량 제한 시 어떻게 유튜브 검색을 제공하지?"
유튜브 API 제한 시 크롤링 방식을 차용했고 API 응답까지 반환 시간이 vCPUs 1, Mem 1GB 환경에서 17초가 나왔다. 말도 안되는 시간이었기 때문에 눈엣가시였고 서버 스펙이 증설되었을 때 개선될 것이라는 확신이 있었지만 스펙은 고작. 기존보다 2배 증가할 뿐이다. 그렇다면 10초 ~ 12초 정도의 예상 시간이 나왔다.
심지어 위 아키텍처와 정반대로 WEB+WAS가 한 개의 인스턴스에서 동작하고 있고 시스템도 메모리를 사용하고 있으니 1.8GB 내에서 최대한 양보해야 한다. 만약, 동시 호출을 한다면?
그렇게 AWS Lambda로 크롤링 로직을 이사를 보냈다. 그렇게 Mem 3000KB를 할당 하고 API 응답 시간까지 평균 6초가 걸렸고 Lambda의 동시 호출수도 빵빵했기 때문에 Gunicorn의 워커 수 조절로 블라킹 되지 않게 하면 되겠다고 판단했다.
"운영 환경의 모니터링 지표는 어떤걸 수집하지?"
가장 큰 문제는 항상 메모리였다. 늘 CPU는 High Usage 60%정도가 최대 기록이지만 메모리는 늘상 부족해서 자주 터졌다.
CloudWatch 모니터링 대시보드를 커스텀 해서 필요한 정보만 수집하도록 작업을 진행 했다. 일단 가장 중요하게 여겼던 메모리, CPU, Disk, Network를 삼았는데 지표를 수집 하기 위해 the USE method를 읽고 해당 Resources 부분만 지표로 수집했다.

"내부망에 있는 RDS를 어떻게 GUI로 접근 해야하지?"
기존 개발 서버에서는 sqlite3와 같은 파일 디비를 사용해서 shell command로 데이터를 확인했다. 예전 같았으면 별 불편함 없이 사용 했겠지만 사내에서도 GUI 환경에 적응하다보니 터미널로 데이터를 보는게 너무 불편해서 조금 이르게 RDS를 구성했다.
RDS의 DB로 dev, prod 환경을 분리 하여 사용 했는데 그럴 때마다 이 데이터를 어떻게 확인 해야하지? 싶었다.
인스턴스는 현재 Bastion Host 없이 Inbound Roule에 개발자 로컬 IP가 등록 되어있지 않다. 오로지 AWS Session Manager를 통해 접근한다.
그렇게 불티나게 구글링을 하던 도중 SSM Port Fowarding 방식을 알게 되었고 개발 서버를 거쳐 내부망에 있는 RDS에 접근할 수 있도록 포트 포워딩을 걸었고 결국 성공했다.
엄청난 쾌감에 해당 내용을 Private RDS SSM 포트 포워딩을 활용하여 GUI로 접근하기 라는 블로그 아티클로 남겼다.
"국내 IP만 허용 하다보니 GeoIP 메타데이터를 변환할 때 서버가 못 버티는데 어떡하지?"
GeoIP CSV 파일을 변환하는 스크립트 오픈소스를 다운 받아 데이터 가공을 진행했다. 순조롭게 진행 했었던 기억이 있었기에 별 다른 문제 없을 것이라고 판단 하고 스크립트를 쭉 돌렸는데 갑자기 서버가 터진 것이다.
운영 서버 환경은 T3.small(vCPUs 2, Mem 2GB) 환경에서 돌렸고 시스템 메모리를 제외한 1.8GB가 너무 제한적이었다. 부랴부랴 세션 2개를 맺은 뒤 한 쪽에서 스크립트를 구동하고 한 쪽은 htop을 통해 서버 성능을 모니터링 했을 때 메모리가 터지는게 눈에 보였다.
그렇게 SWAP Memory를 할당했고 현재 리소스의 두 배인 4GB를 할당한 뒤 제대로 적용 되었는지 눈으로 확인하고 스크립트를 재실행했다.
결과적으로 1분안에 끝나면서 해외 IP 접근 차단까지 잘 진행 되었다.
내가 마주한 문제를 해결한 뒤 짜릿함도 재밌었지만 이번 프로젝트에서 새로운 기술도 많이 적용 시켜본 것 같다.
이렇게 기술을 적용 해보면서 사례들을 주변 지인들에게 많이 공유하기도 했고 블로그에도 작성했다.
Bruno: 캘리 프로젝트 깃허브
AWS Lambda: 캘리 프로젝트 깃허브
CloudWatch Custom Metric 수집
SSM + EC2, RDS 접근
VPC default 망이 아닌 C Class 망 구성
NAT Instance: NAT Instance handson 블로그 작성 내용
uv: Rust로 구성된 패키지 매니저, 하지만 도커 환경에서 너무 미숙하여 Poetry로 변경
그럼에도 불구하고 선방한 AWS 서버 비용

"주마등 같은 사이드 프로젝트를 스쳐 보내며"
거의 한 달 정도 시간을 투자해서 사이드 프로젝트를 진행했다. 여기서 너무 아쉬웠던 점은 자바를 공부하던 나 자신을 버렸다는 것인데, 자프링으로 충분한 성공기를 이뤘다면 2024년 최고의 마무리가 되지 않았을까 하는 생각이 있다.
하지만 인간은 언제나 편리함을 추구하는 동물이란 걸 간과했다. 그럼에도 불구하고 이 프로젝트에 진심이었기 때문에 후회되지는 않는다.
돌이켜봤을 때 회사에 출근해서 항상 서버에 접속해서 로그도 뒤져보고 모니터링도 확인하고 N+1 쿼리 최적화를 시켰는데 또 발생한 건에 대해 처리하느라 시간도 쏟아보고 크롤링 시간이 오래 걸려서 Playwright Python을 어떻게든 컨테이너화 해서 ECR에 올리려고 발악했지만 실패 하고 잠깐 사이에 많은 일이 있었던 것 같다.
또 한 번은 사용자에게 보여줄 노래를 선정하는 데 전혀 기술과 관련이 없지만 행복했던 기억도 가득하다.
잘 하고 싶었고 인생에 한 번뿐인 기회 처럼 달려들었고 매일이 해커톤인 것 처럼 개발했다. 그럼에도 불구하고 기술적 불안감은 아직도 가득하다. "그 때 이렇게 처리를 더 할 걸, 코드를 더 다듬을걸" 그렇게 개선점을 이 프로젝트에 묻고 다음 더 나은 길을 만드는데 일조하게 될 중요한 발판이다.
Last updated