여인수
들어가며
세상에 좋은 프로젝트는 많지만, 실제로 쓰이는 프로젝트가 더 유의미하다고 판단하기에 유저가 실제로 사용하는 프로젝트를 만들기 위해서 Now, Here 프로젝트를 기획했습니다.
이번 서비스 운영 기간인 10월 1일 ~ 10월 10일 간 평균 DAU 76명, 최대 DAU 281명을 기록하는 등 마케팅에 돈을 들이지 않았음에도 많은 유저 분들이 사용하였고, 감사하게도 다양한 피드백을 받을 수 있었습니다.
해당 프로젝트의 백엔드를 개발하면서, 단순히 API만 만드는 것이 아니라 많은 트래픽을 감당하기 위해서 어떤 고민들을 하고 구현했는지, 단순히 매칭을 연결해주는 것이 아니라 유저들을 어떻게 연결하려고 생각했는지, 실제로 서비스를 운영하면서 일반적인 사이드 프로젝트를 만들었을 때는 다른 어떤 고민들을 했는지 설명하겠습니다.
해당 내용과 관련해서 각각 글 한 개 이상의 내용이라, 자세한 내용은 블로그 글을 첨부하거나, 해당 관련된 개발자의 이메일을 첨부할테니 연락주세요!
DB 아키텍처 설계
이번 프로젝트의 아키텍처를 설계하면서 참고한 이론은 CAP이론입니다.
CAP이론이란 아래의 세 가지 특성 중에서 세 가지를 동시에 만족할 수 없다는 이론입니다.
Consistency (일관성):
모든 노드에서 데이터를 읽을 때, 항상 동일한 최신 데이터를 반환하는 특성
Availability (가용성):
시스템이 언제나 응답할 수 있는 상태를 유지하는 특성
Partition Tolerance (네트워크 분할 내성):
네트워크가 분할되더라도(노드 간에 연결이 끊어지거나 통신 장애가 발생하더라도) 시스템이 계속해서 동작할 수 있는 특성
저희 팀의 경우, 분산 시스템을 통해서 로드 밸런싱 및 가용성 측면에 집중해 구현하기로 계획했습니다. 그래서 데이터베이스를 M -S 아키텍처로 설게하여 M 서버가 끊어지더라도 S 서버를 M 서버로 승격 시켜 유저들 입장에선 차이를 느끼지 못하도록, 고가용성을 보장했습니다.
또한 CUD 연산은 마스터 서버로, R 연산은 슬레이브 서버로 나누어서 평소에도 로드 밸런싱을 하여, 서버 자체의 성능 또한 향상 시키고 확장성을 보장하였습니다.
성능 테스트 및 최적화
저희는 또한 성능 테스트를 통해서 병목 지점을 찾고, 이를 최적화하는 경험을 해보았습니다.
이 내용은 무척 길기에, 자세한 내용이 궁금하시다면 아래의 블로그를 참고하시기 바랍니다.
https://jun10920.tistory.com/40
위 블로그 글들의 내용을 요약하자면
성능 목표 잡기
HikariCP의 연결 최대 풀 설정
Caffeine 캐시 설정 및 적용
인덱싱 및 트랜잭션 관리 최적화
하드웨어 리소스 업그레이드
과정을 통해서 SW와 HW 관점에서 최적화를 진행하였고, 목표였던 TTFB를 3초 안으로 줄이는데 성공했습니다.
SW 관점에서 최적화를 했을 때도, 전체 TTFB(응답속도)를 약 40%퍼센트 이상 개선하는데 성공했지만 하드웨어 리소스를 업그레이드 하니 약 99%가 개선되면서, 역시 돈이 짱이구나…하는 생각은 했습니다만 그래도 부족한 자원 속에서 착즙하는 이 경험은 백엔드 개발자로서 굉장히 뜻깊은 경험이었습니다.
실시간 유저 활동 기반 매칭 알고리즘
과거에 다른 프로젝트에서 FOF(친구의 친구를 조회해서 추천)알고리즘을 통해 유저들끼리 매칭하는 로직을 작성한 적이 있습니다.
하지만 이번 프로젝트에서는 FOF보다 좀 더 고도화된, 유저들의 피드백을 직접적으로 반영하는 알고리즘을 구현하고 싶었습니다.
그래서 처음에는 네이버 폼으로 주변인들과 개발 커뮤니티를 통해 설문 조사를 하여 약 8~90명의 데이터를 얻었습니다.
하지만 각 성별 당 MBTI 16개(총 32개의 경우의 수)로 따졌을 때, 각 경우마다 약 3개 정도의 데이터 밖에 얻지 못하였기에 신뢰성이 낮다고 판단했습니다.
그래서 다음에 고안한 것은, 실시간으로 유저들이 매칭되는 것을 반영하여 가중치를 조정하면 원래 목표했던 바를 이룰 수 있다고 생각했습니다.
그래서 실시간으로 유저들이 매칭 되는 것을 반영하여 동적 가중치 조정법을 통해서 반영했고, 하루에 한 번 이 데이터들을 스케줄러를 통해 저장하고, 데이터를 분석하여 관리자 입장에서 인사이트를 얻을 수 있게 자동화 했습니다.
실시간으로 유저들이 매칭 되는 것을 동적 가중치 조정법을 통해서 반영
하루에 한 번 이 데이터들을 스케줄러를 통해 저장
데이터를 분석하여 관리자 입장에서 인사이트를 얻을 수 있게 자동화
이 과정 또한 더 자세한 내용은 아래의 블로그 링크에 있으니 궁금하시다면 확인 하시기 바랍니다.
https://jun10920.tistory.com/38
최소 비용으로 인프라 구축 도전
저희가 세운 가장 중요한 목표는 “운영”입니다. 운영을 실제로 해봐야 사용자의 니즈를 알기 쉽다고 생각했습니다. 특히, 처음 서비스를 운영해 보는 입장에서 운영하기 위해 갖춰야 할 기본적인 역량을 얻고 싶었습니다.
서비스를 실제로 운영하려면, 가장 기본인 운영 인프라 환경이 필요합니다. 이전에 Cloudtype이라는 서비스를 이용해서 개발 서버를 쉽게 배포해 본 경험이 있으나, 프리티어의 경우 제한된 하드웨어 리소스와 특정 시간에 인스턴스가 자동으로 꺼지는 큰 단점이 있었습니다. (물론 무료라서 너무 잘 쓰고 있습니다. 호호호) 또한 단점과 별개로, 서비스 운영 시 적어도 vue application, spring application, postgresql이 실행될 공간이 필요했기 때문에 인프라 구축은 필수적이었습니다.
이번 기회로 처음 운영 인프라를 구축해 볼 수 있었는데요. 초보자인 제 시점에서는 비용과 성능을 가장 먼저 고려했습니다. 그 중 특히 비용을 더 중요하게 생각했습니다.
나우히어 팀 사비를 털어 모은 프로젝트 예산이 있지만, 대부분이 SMS 전송 비용으로 사용되어야 했기 때문에 인프라를 구축하고 운영하는 비용을 줄여야 했습니다. 또한, 이전에 인프라를 구축해본 경험이 없어서 서비스 요구 사항에 적합한 리소스 사양을 산정하는 것이 어려웠습니다. 따라서, 무료 티어에서 제공하는 기본 리소스를 우선적으로 활용하여 인프라를 구축하고, 이후 필요한 요구 사항이 생기면 점진적으로 조정해 나가자는 목표를 세웠습니다.
무료 서비스를 담백(?)하게 제공하는 클라우드 서비스를 찾는 것이 최우선이었습니다. 아래는 제가 생각하기에 참 담백한 프리티어 서비스입니다. (오라클 클라우드)
상시 무료라는 것은 평생 무료라는 것이겠죠.
학습용으로도 최고이지만, 저희처럼 프로토타입을 빠르게 배포하고 성능 요구사항을 산정하는 것에도 적합하다고 생각했습니다.
유일한 단점은 AWS 보다 참고할 레퍼런스(블로그 글, youtube 영상 등)가 부족한 게 아닐까 싶습니다. 일단 제일 잘하는 맨땅의 헤딩을 시도했습니다. 스스로 많이 부족하다고 느낀 과정이었습니다.
now-here.site 도메인을 구매해서 DNS 서버를 Cloudflare로 이전하고, DNS 레코드를 지정해야 하는데, 레코드 개념도 몰라서 학습하느라 간단한 아키텍처도 구축이 오래 걸렸습니다. 가능하면 구축하는 과정에서 필요한 지식을 배우고 가려고 했습니다. DNS resolving 과정이나, private/public subnet을 왜 나눠야 하는지, bastion 서버가 필요한 이유, NAT 게이트웨이를 통한 외부 API 호출 방식 등 궁금한 게 정말 많았어요. (여전히..)
그래서 인프라를 구성하며 한 번에 이해하기 어려운 것들을 도구를 이용해 정리하려고 노력했습니다. (개인적으로는 흐름에 따라 동작을 한 눈에 볼 수 있을 때 이해하기가 수월한 거 같아요 )
아래 그림은 ‘나우히어’ 인프라 아키텍처보다는 초안 스케치에 가까운데, 머릿속에서 뒤엉킨 것들을 시각화하면서 정리하려는 시도라고 봐주시면 좋을 것 같아요.

다음은 위의 스케치를 보고, 구축하면서 어떤 고민들을 했는지 간략하게 설명하겠습니다.
1. GitHub Actions & Docker 활용한 CI/CD
GitHub Actions
Github 코드 베이스와 쉽게 통합시킬 수 있는 환경이자 무료입니다. (최고)
CI/CD 파이프라인을 자동화함으로써, 반복적인 배포 과정을 줄이고 실수를 최소화할 수 있을거라고 생각했습니다.
secret key를 쉽게 관리하지만, 런타임에 주입하면서 안전성을 확보하려고 했습니다.
Docker
도커 이미지는 환경의 일관성을 보장해주기 때문에 코드와 의존성을 이미지로 빌드해 쉽게 배포할 수 있을거라고 생각했습니다. (하지만 러닝 커브는 높았습니다…)
버전 관리하는데 크게 도움이 될거라고 생각했습니다.
빌드/배포 환경을 미리 이미지화해서 파이프라인에서 사용하면, 배포 시간을 크게 단축시킬거라고 생각했고, 실제로 Vue 빌드/배포 시간을 50% 단축할 수 있었습니다.
2. Oracle Cloud Infrastructure (OCI) 선택
Oracle Cloud
상시 무료 티어를 제공하여, 비용을 절감하면서도 필요한 기본 인프라를 갖출 수 있었습니다.
프리티어인데도 불구하고, Object Storage, Container Registry, VM 인스턴스 등 여러 리소스를 통합적으로 관리할 수 있습니다.
3. Cloudflare 사용한 DNS 및 CDN
Cloudflare
CDN 기능을 통해 정적 리소스를 빠르게 전달하고, Edge Location에 캐싱하여 불필요한 네트워크 요청을 줄일 수 있다고 판단했습니다.
DNS 관리와 함께 프록시 설정을 통해 서버로의 트래픽을 효율적으로 전달할 수 있을거라고 생각했습니다.
Worker를 이용하면 부적절한 접근에 대한 에러 페이지를 Cloudflare 단에서 처리할 수 있습니다. 서버에 도달하기 전에 오류를 차단하고, 사용자에게 적절한 에러 메시지를 빠르게 제공하려고 고민했습니다.
4. 로드 밸런서와 라운드 로빈 전략
로드 밸런서를 통해 트래픽을 각 서버에 고르게 분산하고, 라운드 로빈 방식을 적용하여 고가용성을 유지하고 서버 간 부하를 균등하게 분산할 수 있다고 생각했습니다. (다만, 저희처럼 인 메모리에 캐싱해둔 데이터가 있다면 동기화 문제를 고민해야 합니다.)
이를 통해 서비스가 다운되지 않고, 무중단 배포가 가능한 구조를 만드려고 했습니다.
5. Object Storage로 정적 파일 호스팅
정적 파일(HTML, CSS, JavaScript 등)을 Object Storage에 호스팅하여, 비용을 절감하면서도 빠르고 안정적인 파일 전송을 구현할 수 있습니다.
Cloudflare와 연동하여 CDN으로 전달함으로써 시너지 효과를 낼 수 있다고 생각했습니다.
이번 도전기는 정말 새로운 경험이었고, 배우는 게 많았습니다. 처음부터 끝까지 배워가며 하나씩 직접 해보는 과정이 쉽지는 않았지만, 어려움을 극복할 때마다 어느 정도 성장하고 있다고 믿습니다!
기본적인 아키텍처와 CI/CD 파이프라인을 설정하고 나니, 배포 속도는 물론이고 운영 편의성도 크게 향상된 게 느껴집니다. 특히, 제가 두서없이 시도했던 것들이 팀원들에게는 자동화된 형태로 결과를 보여줄 수 있다는 점이 가장 보람찼던 것 같네요.
앞으로도 서비스 성능 요구사항에 맞춰 개선해야 할 점들이 많이 남아있지만, 팀원들과 함께 지속적으로 배워가며 발전해 나가고 싶습니다.
나우히어 프로젝트에서 인프라 구축과 CI/CD 자동화에 처음 도전한 이 경험이, 다른 사람들에게도 새로운 도전을 위한 동기부여가 되었으면 좋겠습니다~
마무리하며
앞으로도 서비스를 운영하면서, 유저 피드백과 서비스 요구사항에 따라 능동적으로 개선해 나갈 계획입니다. 현재 운영 중인 피드백을 반영해 더 나은 서비스를 만들고, 다음 운영에서는 한층 발전된 나우히어를 선보이는 것이 목표입니다 :)
10월 31일까지 나우히어를 한 번 사용해보시고, 소중한 피드백을 남겨주시면 정말 감사하겠습니다!
Now, Here (now-here.site)