Serverless로 E-Commerce 만들기 / 블랙프라이데이 트래픽 썰 / 스타트업에서 CTO는 뭘 하는 자리인가?

Kurt Lee
14 min readJan 31, 2022

--

제가 블로그를 쓴지도 정말 오래 된 것 같습니다. 일하느라 바빴어요.

오늘은 제가 캐치패션에서 CTO로 일한 2년 8개월 정도를 돌아보고

  1. 왜 serverless로 다시 만들었나?
  2. E-Commerce는 뭐가 달랐나?
  3. 블랙프라이데이 트래픽 썰
  4. 스타트업에서 CTO는 무슨 일을 하는 자리인가?

이렇게 4가지 주제에 대해 최대한 짧게(?)
제가 평상시에 해온 생각과 경험을 이야기 해보려고 합니다.
각 주제가 딱히 관련이 있는건 아닙니다.

캐치패션 이직한뒤로, “거기서도 100% serverless로 하실꺼냐"
라는 질문을 정말 많이 받았습니다. 나름 AWS Serverless Hero니까 당연한 질문이지.. 싶으면서도, 솔직히 저는 이게 무척 무의미한 질문이라고 생각해왔습니다.

물론 개발자로서 특정한 기술이나 컨셉을 극단으로 밀어붙이는거
— 정말 재밌고 좋지만
사실 회사에서 개발을 한다는건 비즈니스, 제품, 나아가서는
우리가 원하는 UX를 최대한 효율적인 투자로 만들어내는게 목표지,
“나는 특정 기술로만 만들었어!” 가 목표이면 안되기 때문입니다;

특히 스타트업 이라면 더더욱 그렇습니다.

여튼, 결론부터 말하자면 캐치패션에서는

  1. 결국 시스템을 거의 100% Serverless로 만들었고
  2. 개발자 6명이서 아래 기능을 포함한 E-Commerce 전체를 개발 / 운영하고
    - 350만개 이상의 상품 정보를 수집 / 처리
    - 주문/결제/취소/반품등 주문처리 시스템
    - 실시간 가격/재고 변동 알림 시스템
    - 직접 tranning 시킨 ML Model로 Image Classification / Masking
    - 브랜드/카테고리/사이즈 normalizing
    - …
  3. 블랙프라이데이에는 아무런 수동 작업 없이
    평상시의 100배 정도의 순간트래픽을 감당했습니다.

1. 왜 serverless로 다시 만들었나?

캐치패션은 제가 입사한 시점에 이미 만들어진 제품이 있는 상태였습니다.
NodeJS + AWS Elastic Beanstalk 올라가있었죠.

이 시점엔 저희가 본격적인 이커머스, 즉 주문/결제 관리를 하지 않고 있었습니다.
고객들은 저희 사이트에서 저희가 모아놓은 다양한 리테일러들의 상품을 보고,
그 리테일러로 이동해서 구매 하는거였죠. 네이버 쇼핑이나 다나와 생각하시면 됩니다.

저는 솔직히 처음 입사 하던 시점에, “시스템 전체 리팩토링을 해야겠다”
생각하진 않았습니다. 제 일은 기술개발을 통해 고객 경험을 창출하는거지, 제가 쓰고 싶은 기술을 쓰는 시스템을 만드는게 아니니까요;
기존에 잘 돌아가던게 있다면, 그걸 잘 재활용 하면서 그 위에 새로운걸 계속해서 쌓아나가는게 아무래도 이성적인 판단이겠죠.

다만 입사해서 시스템을 수정하고 기능을 추가 하려니, 답이 없는 부분이 많았습니다.

  • ElasticBeanstalk라서 트래픽이 늘어나면 수동으로 서버 모니터링 / 관리 해야함
  • 기존 코드가 문서화가 전혀 없는 ES6 Javascript. 당연히 typing / dependency 선언이 전혀 없고, 쓰는 필드 / 안쓰는 필드 구분이 불가능하고, 각종 monkey-patching에 순환참조까지.. 코드를 수정을 몇분만에 해도, 배포하기전 깨지는게 없는지 체크하는게 몇시간 걸림.
  • 서비스 특성상, 좋은 상품 (흔히 핫딜) 이 풀리는걸 우리가 미리 알거나 통제할 수 없는데, 발생하면 트래픽이 수십배 급증함.

더군다나 이 시점에서 캐치패션 서비스는 비즈니스 목표를 위해 반드시 필요한 기능들 (가격 알림, 주문 / 결제 관리 시스템, 컨텐츠 작성, 모바일 앱…)이 대부분 만들어지지 않은 상태였습니다.. 앞으로 배포가 수백번, 수천번은 필요할 텐데
“이 변수 쓰는곳이 있냐 없냐?”,
“트래픽 올라가는것 같은데 서버 미리 올려놨냐?”
같은 단순한 문제들로 낭비할시간이 없었죠.

그래서 제가 가장 자신있고, 저희 팀원들도 익숙했던 Typescript + AWS Lambda 기반의 Serverless Microservice Architecture 로 완전히 이전하기로 했습니다.

이 전체 System Migration 과정이 대략 4개월 정도 걸렸는데,
제가 이 회사에 와서 했던 다양한 기술적인 결정중 가장 잘한 것 이였다고 생각합니다.

배포는 100% 자동화되어, git master push 후1~2분 뒤면 배포되게 되었고,
시스템은 거의 100% serverless가 되어, 후술 하겠지만 트래픽 변화에 대처하는 운영 업무가 사실상 없어지게 되었습니다.

2. 이커머스는 뭐가 달랐나?

저는 빙글에서의 이전 경험 을 통해, 거의 모든 web application은 다 serverless로 작성될 수 있다는 확신을 가지고 있었습니다.
빙글에선 아래의 내용을 전부 100% serverless 로 구축해 봤었거든요.

  • Websocket 기반 실시간 채팅
  • Transaction-Safe 투표 시스템
  • GIF → Video encoding
  • 광고 및 사용자 반응 실시간 수집
  • Athena 기반 big data analytics

좀 김빠지는 이야기겠지만, 사실 이커머스라고 별 다를건 없었습니다;
지나와서 하는 이야기지만 저도 시작하기 전엔

“혹시 다른 사람들 모두 이커머스는 Java Spring 으로 하는 나만 모르는 이유가 있나?”

뭐 이런 자기 의심도 있었는데, 해보니까 — 그냥 하면 되더군요;
제가 이 글에서 다시한번 강조하고 싶은 내용이기도 한데요.

왠만한 Web Application은 다 Serverless로
만들수 있습니다.

그냥 해보세요

다만 이커머스 비즈니스에서 제가 개인적으로 처음 겪은 근본적인 어려움은

“고객이 아닌 다른 비즈니스 주체들과 협업해야 한다”

는 겁니다.

빙글에서 제가 신경을 쓴 유일한 주체는 고객 이였습니다. 컨텐츠 플랫폼이니, 고객들이 컨텐츠를 쉽고 편하게 많이 찾아볼수 있으면 — 성공인거죠.

이커머스는, 특히 플랫폼 사업은 그렇게 간단하지 않습니다. 다양한 주체와 서로 상충하는 이해관계가 존재하고, 여기서 발생하는 모순과 복잡도는 개발 / 프로덕트로 그대로 흘러들어옵니다.

소프트웨어 제품에서의 복잡도는 마치 하수와 같습니다. 만들어내는 높은쪽에서는 이정도야~ 하면서 버리지만, 결국 낮은곳으로 흐르고 흘러서 하수 처리장에 가보면 내가 대충 버린 샴푸와 비누와 오수가 얼마나 복잡한 화학 처리 과정을 거쳐야 자연계로 돌려보내질수 있는지 놀라게 되죠;

E-Commerce 에서 이게 두드러지는 대표적인 예시를 하나만 들자면,
바로 아주 기본적인 주문 처리 입니다.

주문 상태 관리

캐치패션에서는 캐치구매 라는 이름으로 직접결제/주문 서비스를 제공 하는데요.

https://www.catchfashion.com/about/catch-order

대략적인 프로세스는 아래와 같습니다.

1. 캐치패션이 다양한 리테일러의 상품을 모두 모아서 보여주고
2. 고객들은 그중 원하는 상품을 구매하여 캐치패션에 결제하고
3. 캐치패션이 리테일러에 주문을 발주하고
4. 리테일러들이 주문을 배송하고
5. 고객이 취소/반품/주문 확정을 하고

문제는 (3)/(4)/(5) 프로세스가 리테일러 마다 선호하는 방식이 다 다르다는 겁니다.
이유는 그냥 이 프로세스를 수행할 능력/자원이 없어서 부터, 그냥 이 프로세스로 하는게 더 효율적이라고 생각해서 까지 아주 다양 합니다만,
하여간 결론은 이게 다 다릅니다;

발주
- 어떤 리테일러는 API를 통해서 실시간으로 주기를 원하고,
- 어떤 리테일러는 매일 정해진 시간에 주문 목록을 Excel로 만들어서 이메일로 보내주길 원하고
- 어떤 리테일러는 발생할때마다 수동으로 자기 사이트에서 주문을 넣어주기를 원하고

배송
- 어떤 리테일러는 고객에게 직접 국제택배로 배송 하기를 원하고,
- 어떤 리테일러는 캐치패션에게 국제택배로 보내면, 캐치패션이 받아서 다시 고객에게 보내기를 원하고

취소/반품/주문 확정
- 어떤 리테일러는 캐치패션이 발주를 넣으면 취소가 아예 불가능하고
- 어떤 리테일러는 캐치패션이 발주를 넣었어도, 배송 시작 전이면 취소가 가능하고
- 어떤 리테일러는 일단 발송이 시작 됬으면, 상품이 고객에게 도착해야 반품이 가능하고
- 어떤 리테일러는 일단 발송이 시작 됬어도, 상품이 고객에게 도착하기 전에 반품 (내지는 취소) 가 가능하고

결과적으로, 리테일러마다
- 주문이 가질수 있는 state / attribute가 아예 다르고
- 우리 내부 Admin이 취할수 있는 action 자체가 아예 다른
상황이 생겼습니다.

심지어, 캐치구매의 핵심은 유저가 여러 리테일러의 상품을 한번에 하나의 주문으로 checkout 가능하게 하는 것 이였기 때문에, 서로 주문 처리 방식이 다른 리테일러들을 하나의 주문에 넣을수 있어야 했습니다;

하지만 고객에게 그걸 다 다른 형태로 보여주는건 당연히 말이 안되죠
— 고객은 그냥 돈 내고, 물건 배송받고, 주문 확정 하고 하는거니까요.
그래서 고객에게는 “주문확정" / “취소" / “반품" 등 같은 라벨로 보여주지만,
실제로는 리테일러나 주문형태에 따라서 아예 다른 액션이 수행되어야 했습니다.

이 문제 때문에 초창기에 캐치패션 프로덕트 팀에서는 아주 긴 — 논의를 거쳤습니다.

결과적으로, 캐치패션에서는 이걸 고전적인 State Machine 문제로 취급 하기로 하고,
https://xstate.js.org/ 를 이용하여 주문 처리 상태 / 주문에 어드민/고객이 취할수 있는 액션을 전부 State Machine으로 만들고, 그걸 AWS Lambda에 serverless application으로 올렸습니다.

3. 블랙프라이데이 트래픽 썰

아마 이 글을 클릭하신 분들중 많은 분들이 여기에 낚이셨을 것 같은데요.
인생의 많은 것들이 그렇듯 — 정말로 대단하고 찬사를 받을만한 것들은 오히려 대단한 비법이 없습니다. 그냥 한 겁니다.

당시 트래픽 그래프

캐치패션에서는 블랙프라이데이 전후로 몇몇 광고 캠페인이 터지고, 그게 바이럴을 타면서 엄청난 트래픽이 발생했습니다. 평상시 동시간대로 비교하면 100배가 넘었습니다.

당시 Request Success Rate (로그인 비밀번호 불일치등 단순 에러 포함)

하지만 당시 저희 backend의 success rate와 latency는 아무런 변화가 없었고, 당시엔 개발자중 그 누구도 모니터링을 하고 있지 않았습니다. (다들 각자 개발 열심히 하고 있었습니다..) 아무런 알림이 울리지 않았거든요;

캐치패션의 백엔드 시스템은 아주 일부 컴포넌트 (Aurora Mysql RDS, OpenSearch, Redis)를 제외하면 100% Serverless로 이루어져있습니다.
트래픽이 급증해도

  • 단순 상품 조회는 거의 100% 캐시가 되었습니다.
    이커머스 특성상 유저가 주문을 하지 않는 이상 상품 정보는 거의 바뀌지 않고,
    빙글과 마찬가지로, 이런 바이럴을 통한 급상승의 경우 정말 인기 있는 컨텐츠 (혹은 상품) 상위 20개가 전체 트래픽의 50~60% 를 차지하기 때문에 대부분의 트래픽은 RDS / OpenSearch등 serverless가 아닌 컴포넌트의 트래픽을 증가시키지 않았습니다.
  • Frontend는 CloudFront + S3 + Lambda로 이루어진 100% serverless구조라, 100x 트래픽 증가에 아무런 영향을 받지 않았습니다. (실제로 트래픽은 튀었습니다)
  • API Server는 AWS API Gateway + AWS Lambda 로 이루어진 100% serverless구조라, 100x 트래픽 증가에 아무런 영향을 받지 않았습니다. (실제로 트래픽은 튀었습니다)
  • “고객이 최근에 클릭해본 상품 목록" 등, 암묵적인 User Interaction을 실시간으로 처리하는 시스템의 경우, 전부 DynamoDB로 되어있어서 마찬가지로 트래픽 증가에 영향을 받지 않았습니다. (실제로 트래픽은 튀었습니다)

딱히 특별한 비법은 없었습니다.
그냥 시스템을 전부 Serverless로 만들면 — 트래픽 걱정을 안하게 됩니다.

4. CTO는 뭘 하는 자리인가?

저는 제가 직접 CTO 롤모델로 삼을만한 사람과 직접 함께 일해본적이 없습니다. 빙글은 애초에 CEO외에는 C레벨이 존재하지 않는 완전 flat 구조였고,
제가 빙글에서 6년 반을 있으면서, 후반부엔 제가 가장 경력이 긴 편이였고요.

그리고 다양한 회사의 CTO들을 만나봤지만, 회사마다 하는 일이 너무 달랐습니다.
어떤 곳은 그 팀에서 개발을 가장 잘 하는 사람
— 즉 Technical Leader 역할을 중요하게 생각했고,
어떤 곳은 개발과 Business 요구를 bridging 하고 채용에 집중하는 사람
— 즉 Technical Manager / Product Owner 역할을 더 중요하게 생각하고요.
하다못해 제가 존경하는 회사의 CEO 들로 부터도 이 질문에 대해서 모두 다른 답변을 받았습니다. (대부분 직접 물어본게 아니라 인터뷰를 본거지만)

제가 2년 반의 경험과, 직관에서 배운 답은 이렇습니다:

  1. 스타트업에서 “고정적인 역할"은 존재하지 않는다.
    회사와 비즈니스가 성장함에 따라 필요한 역할이 계속해서 새로 생기고,
    구성원들 모두가 성장하면서 필요한 역할을 채워나가야 한다.
    성장하지 못하는 구성원이 많은 스타트업은 반드시 실패한다.
  2. 일반론으로, 스타트업에서 CTO는 크게 아래 4가지를 충족해야한다.
    (1) 개발팀에서 가장 기술선택과 결정을 잘 하는 사람
    (2) 개발팀에서 회사 전체의 목표와 비즈니스 요구사항을 가장 잘 알고, 이걸 기술적으로 Trade-off 를 할수 있는 사람
    (3) 개발팀에게 해야하는 Task의 당위성을 설득할수 있는 사람
    (4) 개발팀원들이 배울게 있다고 생각하는 사람

저는 개인적으로 (2)/(3) 가 언제나 가장 어렵다고 느낍니다. 가끔씩 저희 개발자들이
“아니 이걸 왜 이렇게 복잡하게 만들어야 하나요?” 라고 하면 저도 답을 모르거나,
저도 왜 해야하는지 모르겠는 작업을 해야할때가 생기거든요. 그럼 개발이 문제가 아니라, 비즈니스를 (혹은 CS를, 혹은 마케팅을) 이해하고, 회사 전체의 투자 관점에서 이 일을 하는게 왜 말이 되는가 — 를 이해하는게 제 일이 됩니다.

개발을 잘하는걸로 CTO 자리에 도달한 많은 사람들은 언제나 (1)에 집중하게 되는 경향이 있는것 같습니다. “나도 한명의 개발자로서 개발만 정말 잘하면 되지” — 같은거죠.
이것도 물론 맞는 말입니다. 저만 해도 아직도 주로 하는일은 개발입니다.
그리고 이게 마음이 편하죠. 그냥 내가 잘하는 개발만 하면 되니까요.

다만 이 단계에서 우리가 간과하는게 있습니다. “단순히 개발을 잘 하는 것" 으로 해결되지 않는 문제가 훨씬 많다는 겁니다.

스티브 잡스가 언젠가 이런말을 한적이 있습니다.

“언제나 고객 경험에서 먼저 시작해서, 어떻게 하면 그 경험을 만들어낼수 있을지 고민해서 기술을 만들어내야 한다.
반대로, 기술을 먼저 선택하고, 그 기술을 어떤 고객경험으로 만들어내야 팔수 있을지
고민하면 반드시 실패한다. 이건 내가 많이 해봐서 안다.”

개발자들은 CTO든 아니든 이런 함정에 쉽게 빠집니다. 어떤 기술적인 요구 사항을 들으면, 그냥 그걸 빨리 개발하는걸로 만사가 해결될꺼라고 믿어버리는거죠.
그리고 그게 자연스럽습니다. 많은 경우에 개발자들은 문제가 주어지고, 그 문제를 빨리, 잘 해결하는걸로 평가 받으니까요. 개발자에게 문제 그 자체를 의심하고,
“그 문제를 풀어야 하는 당위성을 이해하는" 일을 시키는 경우는 드물죠.

다만 스타트업에서는 대부분의 경우, 그걸로는 불충분합니다.
문제가 주어지면 발벗고 문제를 해결하려고 하기 이전에, 이 문제가 풀 가치가 있는것인지, 이게 기술로 해결되어야 하는게 맞는지, 이게 미래를 생각해도 지금 투자하는게 가치있는것인지 고민해야합니다.
그냥 개발자든, CTO든 말입니다.

그래도 스타트업

2022년 2월이면 제가 스타트업에서 일하기 시작한지 9년이 됩니다.
그때 첫 출근하던 옛날 빙글 사무실이 지금 제가 있는 캐치패션 사무실에서 걸어서 5분 거리인 우연도 생각해보면 참 수미상관 이군요.

그 사이 참 많은걸 배웠습니다. 개발자로서도 그렇고, 스타트업에서 어떻게든 의미있는 제품과 서비스를 만들어 보려는 사람으로서도 그렇습니다.

여러모로 고생 많이 했지만,

적어도 스타트업에서 일하는걸 후회하지 않는 커리어를 쌓은건
다행이라고 생각합니다.
“대충 직원들 많이 착취해서 내가 돈 많이 벌 수 있는 사업하자~” 류의
“사업가" 전염병에 휩쓸리지 않은것도요.

저는 여전히 의미있는 제품 / 서비스를 만드는게 목표입니다.
그러려면 스타트업 해야하더라고요. 앞으로도 그러려고 노력하겠습니다.

--

--

Kurt Lee

AWS Serverless Hero, Seoul. Love building beautiful product, Proudly working hard at startup. Serverless, Typescript, AWS, Microservices