본문 바로가기

TIL/DevLog

대국민 질문 회고

2020년 3월 아주 우연한 기회로 외주 프로젝트를 하게 됐다. 취직 후 적응하느라 바빠서 그동안 블로깅을 못하고 있었지만 프로젝트를 진행하며 배웠던 것들을 기록해두고 싶어 이렇게 키보드를 잡았다.

 

 

이머시브 코스 수료 후 한창 취업준비를 하던 중, 다른 수료자분께서 자신이 하던 외주에 백엔드 인력이 필요해져서(그 분은 프론트엔드 개발자) 한 달 정도 함께 프로젝트를 진행했다.

 

당시 찾아 본 수 많은 레퍼런스들 중 유용했던 사이트를 모아 둔 페이지(추리고 추린 것이 이 정도. 당연히 이 3배는 더 찾아봤고 관련 서적도 인덱스가 너덜너덜해지도록 열심히 읽었다). 그냥 이 정도로 열심히 했다는 것을 적고 싶었다. 프로젝트 회고에는 공부한 것 자랑 하나쯤은 있어야 하잖아요?😎

 

 

서비스는 사회 이슈와 관련된 질문에 대한 유저들의 투표를 받는 간편 설문조사 웹앱이고 문항에 투표한 사람의 성별, 지역, 연령을 분석하여 그래프로 결과를 출력하여 보여준다. 어드민 대시보드도 함께 제작했다.

 

이 프로젝트 덕분에 AWS와 서버에 대해 많이 배울 수 있어서 좋았다.

서비스 gif

내가 맡은 부분은 크게 세 가지이다.

 

  1. AWS 아키텍처 설계
    1. 예상 사용자 만 명을 견딤과 동시에 합리적인 비용의 AWS 아키텍처 설계.
    2. RDS 비용 절감을 위해 AWS RDS Aurora를 사용한 서버 리스 데이터베이스 구축.
    3. 만 명의 예상 사용자를 감당하기 위해 AWS Elastic Load Balancing과 Auto Scaling group 사용.
    4. 서버 관리의 부담을 줄이기 위해 AWS S3와 CloudFront를 사용해 https 프로토콜 웹사이트 배포.
  2. DB아키텍처 설계
  3. API 설계

 

왜 그렇게 설계했는지에 대한 이유와 지금 와서 생각해 봤을 때 아쉬운 점을 적어볼까 한다.

 

(최근 사이트를 찾아가보니 많이 바뀌어있어서 구조도 아예 달라졌을 것 같지만, 혹시 모르니까 AWS 아키텍처에 대한 내용만 적을 예정이다)

 

 


AWS 아키텍처 설계

내가 했던 설계는 다음과 같다.

라우팅은 프론트, 백 할 것 없이 Route 53을 사용했지만 배포는 각각 했다.

  • 프론트엔드
    • 배포: S3 버킷, CloudFront
  • 백엔드
    • 배포: EC2(t2.micro), ELB
    • DB: RDS Aurora Serverless

1. 아키텍처 설계

원래 firebase만을 사용한 서버리스 프로젝트였으나 비용 문제로 백엔드 개발이 필요하게 되어 프로젝트 중반부터 함께하게 되었다. 클라이언트 측이 예상 사용자 수가 만 명 정도 될 것이라 예상했고, 당시 firebase는 사용자 수가 많아지면 비용이 선형적으로 증가했기 때문에(지금은 어떻게 비용을 책정하는지 모른다) 다른 방식으로 서비스를 배포해야 했다.

 

열심히 구글링하던 중 AWS 클라우드로 천만명 웹 서비스 확장하기라는 자료를 발견했고, 이를 토대로 더 공부하여 아키텍처를 설계했다. 4년 전 자료지만 기본적인 내용은 크게 바뀌지 않았을 것이기에 많이 참고했다. 그리고 설계에 대한 전문가의 의견이 궁금했기에 AWS Meet The Expert서비스를 통해 아키텍처에 대한 조언도 들었다.

1-1. 사용자 > 100

기능에 따라 인스턴스의 역할을 나눔

  • 웹 서버용 인스턴스
  • DB용 인스턴스(편리한 DB운영을 위해 Amazon DB 관리 서비스 사용)

여기까지가 내가 알고 있던 내용이었고, 예상 사용자가 많아져서 혹시라도 웹 서버가 다운될 경우 어떻게 해야하나를 고민하고 공부하다 아래 내용을 알게 됐다.

1-2. 사용자 > 1,000

  • Elastic Load Balancing
    • 여러 대의 서버 인스턴스로 서비스를 운영하면 많은 트래픽에 대응하고 서버에 장애가 생겨도 서비스가 안전하게 돌아갈 수 있다.
  • RDS의 마스터-스탠바이를 Multi-AZ에 구성하여 데이터베이스 이중화
    • 원래는 RDS Aurora의 '단일 쓰기 및 다중 읽기'기능을 사용해 데이터베이스 이중화를 구현하려 했었다. 하지만 어느정도의 데이터가 쌓일지 동시접속자 수가 얼마나 될지 알 수 없는 상황이었기 때문에 Aurora의 서버리스 기능을 사용해 DB를 만들었다. 상세한 내용은 아래 항목에서 설명할 예정이다.

가장 많이 고민했던 것은 어떤 인스턴스를 쓸 것인지 선택하는 것이었다. 다른 스택은 변동이 없지만 EC2는 선택의 폭이 넓었기 때문에 정보를 열심히 찾아보고 AWS Meet The Expert를 통해 어떤 인스턴스를 사용하는 것이 적합할지에 대한 상담도 받았다.

 

결국 EC2 인스턴스는 t2.micro를 사용했다. t2인스턴스는 프리티어를 사용할 수 있고, 프론트엔드는 S3로 배포하고 DB는 RDS를 사용할 것이었기 때문에 고사양의 서버를 사용할 필요가 없어 t2로도 충분하다고 생각했다.

 

어떤 계산으로 나온 수치인지 물어보는 것 까지 생각이 닿지 않아 그저 예상 유저가 만명이라는 정보만 가지고 개발했던 것이 아쉽다. 뿐만 아니라 예상 동시접속자 수 등에 대한 정보를 알았다면 더 알맞은 설계를 할 수 있었을텐데 하는 생각이 든다.

2. 데이터베이스 선택

위에도 써놨지만 초기에는 RDS Aurora 서버리스가 아니라 '단일 쓰기 및 다중 읽기'기능을 사용해서 데이터베이스 이중화까지 구현하려 했었다. 하지만 어느정도의 데이터가 쌓일지 예측할 수 없었기 때문에 Aurora 서버리스를 사용하여 쓰는 만큼의 비용만 감당하도록 설계했다.

 

유저가 많으면 DB의 부하가 커지기 때문에(DB는 하나밖에 없으니까) Radis 등(ElastiCache?)으로 캐싱을 구현했으면 좋았을테지만 그 때는 데이터베이스 이중화만 알고 있었기 때문에 데이터베이스 이중화를 하고싶었다. 결국 하나의 DB로 구현하게 되었지만😅

 

대국민 질문 프로젝트를 생각해보면 기억에 남는 에피소드가 하나 있다. 개발 단계에서 실수로 잘못된 인스턴스를 선택해서 327달러의 요금폭탄을 맞은 일이다. 과금 너무 무섭다..!!🥺

2-1. 뼈아픈 실수, 만회의 먹먹문

계약이 끝난 프로젝트라 프로젝트를 진행했던 AWS계정에 접근하지 못하기 때문에 아쉽게도 서비스센터와 주고 받은 문의내역은 없다. 하지만 다행히 처음 보냈던 문의글은 가지고 있어서 그 글을 토대로 기억을 되짚어볼 수 있었다. 프로젝트 중 참고했던 레퍼런스를 모아뒀던 페이지를 잘 보면 당시에 썼던 먹먹문을 찾을 수 있다.😓

 

327달러 과금폭탄은 요금을 잘못봐서 생긴 일이었다. RDS database를 생성할 때 Easy Create(손쉬운 생성)으로 Production(프로덕션)을 봤고, 2.800USD/시간 을 2.800USD/ 로 잘못봤다. 개발단계에서 하루에 2.8달러는 감당 가능한 수준이었기 때문에 괜찮았지만 시간당 2.8달러는 감당할 수 없는 수준이었다..!

 

DB를 생성하고 쓸때까지는 이상을 못느꼈었다. DB 생성과 동시에 Cost Explorer를 활성화했고 활성화 되자마자 비용을 확인해봤는데 327달러가 적혀 있었다. 너무 놀란 나머지 DB를 바로 종료하고 사용하는 만큼 과금되는 Aurora 서버리스로 DB를 새로 생성해 개발을 진행했다. 개발 과정은 모두 리모트로 진행되었지만 개발자 간 커뮤니케이션이 원할했던 덕에 추가과금을 막기 위한 빠른 대응이 가능했다.

 

그리고 바로 먹먹문을 쓰기 시작했고, 구글번역의 도움으로 AWS서비스 센터에 문의를 넣을 수 있었다. 몇 시간 지나지 않아 답변이 왔고 다행히 350달러(얼마짜리였는지 정확하게 기억나지 않지만 327달러보다는 큰 금액이었다!)의 할인코드를 받고 일이 잘 마무리됐다!!!🥳

 

당시 할인코드를 받기 전까지는 밥도 제대로 못먹고, 잠도 못자며 전전긍긍했었지만 잘 마무리돼서 참 다행이다. AWS최고..! 최고!!!

2-2. 서버리스DB

RDS Aurora 서버리스 DB는 사용자가 필요한 최소 및 최대 리소스를 지정하고, Aurora가 데이터베이스 부하에 따라 용량을 조정하는 용량 유형이다. 간헐적 또는 예측 불가능한 워크로드에 적합한 옵션이며 특정 시간 동안의 접근이 없을 경우 자동으로 DB를 끄도록 설정할 수 있어서 비용을 아끼기에 좋을 것 같아 선택했다.

 

물론 배포시에는 항상켜두는 설정으로 해뒀지만 투표라는 특성상 특정 시간에만 사람이 몰릴것 같아 그 외의 시간에는 DB리소스를 줄여 요금을 절감하기 위해 서버리스를 선택하게 되었다.

 

 

지금 생각해봤을 때 특정 시간에만 사람이 몰린다면 서버리스보다 데이터 캐싱이나 데이터베이스 이중화가 더 적절했을 것 같기도 하고.. 그 당시에는 그게 최선이라고 생각했었지만 역시 아쉽다.

3. 웹서버(WAS) 구조

웹서버는 Auto Scaling group을 이용해 다중 서버 환경을 구성했고 로드 밸런싱은 Elastic Load Balancing을 사용했다.

 

ELB(Elastic Load Balancing)은 주기적으로 웹서버들의 상태를 확인하여 정상 상태인 서버에만 요청을 보내는 기능이고 Auto Scaling group은 서버의 수를 트래픽에 따라 자동으로 관리해주는 기능이다.

 

Auto Scaling group을 이용해 저장해 둔 EC2 인스턴스의 이미지(AMI)로 필요할 때 서버를 추가하여 사용자가 서비스 이상을 느끼지 못하게 했다. 서버의 수를 트래픽에 따라 자동으로 관리해어 많은 트래픽에 대응할 수 있고 서버에 장애가 생겨도 서비스가 안전하게 돌아갈 수 있기 때문에 사용했다.

 

Elastic Load Balancing은 클러이언트의 요청을 받고 로드 밸런서가 관리하는 서버들에게 요청을 골고루 전달해주는 역할을 한다. 로드 밸런서도 일종의 서버지만 AWS그 서버를 내부적으로 관리해주기 때문에 SSH로 직접 접근할수는 없다.

4. 프론트엔드 구조

프론트엔드는 S3와 CloudFront를 사용해서 배포했다. 그냥 EC2 인스턴스에 프론트, 백을 함께 두고 배포할수도 있지만 그렇게 되면 더 많은 관리비용이 생길수도 있기 때문에 프론트엔드는 S3의 정적 웹 사이트 호스팅 기능을 사용해 따로 배포했다.

 

CloudFront는 https배포를 위해 사용했다. S3의 정적 웹 사이트 호스팅 기능을 사용하면 http로만 배포할 수 있기 때문에 ClouFront도 함께 사용했다. CloudFront는 S3의 Object들을 유저에게 가장 가까운 Edge에 Caching해두어 요청이 왔을 때 보다 빠르게 Object를 전달해주기 위해 만든 서비스이기 때문에 프론트엔드 앱의 접근속도가 더 빨라진다는 이점도 있다.

 

 


후기 및 다음 프로젝트

코딩을 배울때마다 항상 생각하는것인데 역시 오랫동안 공부하는 것 보다 프로젝트 하나를 하는 것에서 더 많이 배우게 된다. 특히 AWS는 복잡하기 때문에 공부하는것보다 AWS를 사용해서 한 번 배포해 보는게 훨씬 도움이 됐다.

 

어서 초록프로젝트를 이어서 하고 싶은데 다들 새 회사에 적응하느라 너무 바빠서 시작하지 못하고 있는 것이 아쉽다. 새로운 회사에서 주니어 개발자로 일하며 이미 뼈대가 있는 서비스 위주의 개발을 하다보니 0부터 만들고 운영하는 프로젝트에 대한 갈증이 생겼다. 이래서 개발자들이 사이드 프로젝트를 하는구나 싶은 생각이 확 들었다.

 

얼마전까지만 해도 만년필에 꽂혀있었어서 그와 관련된 사이드 프로젝트를 할까 했는데 지금은 관심사가 바뀌어서

  1. 모바일웹용 간단한 목표달성, 체크 앱(추후 모바일 어플로 발전시킬 예정)
  2. 가계부앱

이렇게 최근 필요성을 느끼고 있는 서비스에 대한 프로젝트를 진행해보려고 한다.

 

위 아이디어 둘 다 이미 좋은 앱들이 많지만 '내가 100% 원하는 서비스'는 없기 때문에 한 번 해 볼 생각이다.

화이팅!!