안녕하세요, 오늘의집 Head of Technology 진식입니다. 오늘의집 서비스가 더 빠르고 크게 성장하기 위해 MSA를 채택하고 나아가는 과정을 몇 편의 글로 나누어 공유하고자 합니다. 이번 글은 그 첫 번째로 MSA(Microservices Architecture)를 왜 진행하게 되었는지, 그리고 시작 단계에서 어떤 결단과 실행을 하고 있는지에 대해 작성해보려고 합니다.
오늘의집 서비스 성장과 개발
오늘의집 서비스는 2013년부터 아이데이션 및 테스트하여 2014년 오늘의집 앱을 정식 출시하였습니다. 이후, 2016년 7월 원스톱 인테리어플랫폼을 위한 다음 단계로 커머스 서비스를 오픈하였으며 위 그림과 같이 서비스에 유입되는 회원수가 늘어나면서 급격한 성장을 이뤄내고 있습니다.
이 성장 속에서 오늘의집은 사용자가 인테리어 등 공간을 변화시키는 과정에서 느끼는 Pain Point를 분석하고, 이를 해결할 수 있는 서비스를 제공하는 것에 집중하였습니다. MVP(Minimum Viable Product) 관점에서의 빠른(정말 빠른) 개발과 실험을 통해 많은 문제를 풀어내는데 중점을 두었습니다. 더 좋은 서비스를 만들면 언젠가 더 경험 많고 탁월한 개발자 분들이 합류하셔서 기술적 부채를 해결할 수 있다는 신념으로 앞만 보고 달려온 것이죠.
그 결과 오늘의집 서비스는 2021년까지 모놀리식(Monolithic) 서비스로 성장하게 되었습니다. 하지만 서비스 확장성에서 더 이상 모놀리식으로는 한계가 있다고 판단하였고, 대망의 MSA 프로젝트를 위한 첫발을 내딛었습니다. 그 동안 합류한 뛰어난 개발자 분들의 경험을 통해 이젠 문제를 해결할 수 있을 것이라는 확신도 있었습니다.
Why MSA?
많은 MSA 글에서 나타나는 다양한 문제를 오늘의집 역시 가지고 있습니다. ‘왜 우리가 MSA를 해야하는가’에 대해서 간단히 정리하였던 글을 공유해봅니다.
오늘의집 서비스는 하나의 거대한 모놀리식 구조로 구축되어 있습니다.
이러한 모놀리식 구조는
1) 부분 장애가 전체 서비스로 전파된다.
2) 부분적인 서비스의 scale-out이 어렵다.
3) 서비스의 개선이 어렵고, 수정 시 장애의 영향도 파악이 어렵다.
4) 서비스의 전체 코드가 하나의 프로젝트로 구성되어 배포가 오래걸린다.
5) 하나의 framework와 개발언어에 종속되어 서비스에 적절한 기술을 사용하기 어렵다.
이처럼 여러 문제를 가지고 있고, 이를 개선하기 위해서는 시스템을 여러 개의 서비스로 분리하여
서비스 간의 의존성을 제거하는 MSA로의 전환이 필요합니다.
위 이유에 대해서는 모두가 알고 있는 내용일 것이기에 우리가 어떤 목표와 방향성으로 움직이고 있는지 설명드리겠습니다.
MSA Goals
MSA를 통해 우리는 무엇을 얻을 수 있을까요? 위에서 언급한 MSA 과업의 이유와도 많이 연관되어 있지만, MSA 끝에 우리가 어떤 결과물을 얻을 수 있을지 고민해 보았습니다.
1) 하나의 서비스 장애가 다른 서비스로 전파되지 않는다.
2) 코드 복잡성 및 의존성을 제거하여 영향도 파악을 용이하게 한다.
3) 오늘의집 서비스의 고 가용성과 확장성을 확보한다.
위와 같이 단순히 모놀리식을 MSA로 전환함으로써 얻는 결과 외에 “우리가 달성해야 할 별도의 목표는 무엇일까?” 고민을 하였습니다. 서비스를 구성하는 코드의 형태부터 인프라 아키텍처의 영역까지 서비스가 성장함에 따라 어딘가에 병목이 발생하고, 이를 해결하기 위해 노력하며, 필요에 따라 아키텍처까지 새롭게 빌드하는 과정을 겪게 됩니다. 오늘의집 서비스 또한 이러한 과정을 몇 번 경험하였습니다. 그리고 앞으로 MSA를 진행하게 되면 단순히 서비스를 나누는 것이 아니라, 해당 서비스에 맞게 아키텍처를 다시 설계하고 코드도 새롭게 작성하게 될 것입니다.
우리는 지금이 앞으로의 성장에 대비해 ‘트래픽 대역폭을 확장할 수 있는 기회가 아닐까?’ 라는 생각을 하였습니다. 높은 트래픽을 감당할 수 있게 아키텍처를 구성하고 테스트를 한 후 Scale In 해두면 좋겠다는 생각이 들었습니다. 얼마만큼의 트래픽 향상을 대비할 것인가에 대해서는 국내 시장 상황과 앞으로 확장될 수 있는 사용자, 그리고 비즈니스 확장까지 고려하여 10배를 목표로 잡았습니다. 이렇게 기존 모놀리식의 MSA 전환으로 얻는 이점에 더해 현재보다 10배의 트래픽을 감당할 수 있어야 한다는 기술적 요건을 추가하게 되었습니다.
1) 하나의 서비스 장애가 다른 서비스로 전파되지 않는다.
2) 코드 복잡성 및 의존성을 제거하여 영향도 파악을 용이하게 한다.
3) 오늘의집 서비스의 고 가용성과 확장성을 확보한다.
4) 현 기준 10x 트래픽을 수용한다.
(한때 MSA 프로젝트의 이름을 10x 프로젝트로 부를까도 고민하였습니다.)
MSA 프로젝트의 목표를 설정한 후 어떠한 방향성으로 움직여왔고, 또 움직일 것인지 말씀드리겠습니다.
MSA Preparation
1. Kubernetes
MSA 프로젝트를 진행하기에 앞서 한 가지 먼저 해결했던 과업이 있습니다. MSA에 대한 꿈은 제 개인적으로 약 3년 전인 2019년 1월부터 갖고 있었습니다. 2019년 신년회 자료에 서비스 안정화 과업 중 하나로 MSA 진행을 준비하겠다고 발표했습니다. 서비스 오케스트레이션에 용이하면서도 개발자가 인프라에 대한 많은 지식 없이도 배포가 가능한 환경이 필요하다고 생각하였고, 쿠버네티스(Kubernetes) 적용에 대해 검토하였습니다. 2019년 당시에는 검토에 많은 시간을 할애했고, 실제 적용을 위한 테스팅은 2020년 2월부터 시작되었으며, 레거시 코드에 대한 K8s 이관은 많은 시행착오 끝에 2020년 11월에 끝났습니다. 물론, MSA만을 위해서 쿠버네티스를 선택한 것은 아니었지만요. 그 이야기는 기회가 된다면 다음에 하도록 하겠습니다.
2. Platform Team
Kubernetes 적용을 하면서 느낀 것은 1) 비즈니스 과업과 분리하여 MSA를 준비해야 한다는 것과 2) 오늘의집 내에서 사용할 다양한 플랫폼, 라이브러리를 만들고 관리할 팀이 필요하다는 것이었습니다. 오늘의집 개발과 별개로 각 팀의 요구사항과 경험을 바탕으로 기술과업을 주도적으로 추진할 팀이 필요했습니다. 이에 Kubernetes에 대한 고도화, API Gateway, Service Mesh 등에 대한 PoC 그리고 Auth Service를 만드는 등 다양한 기술 과업을 실행할 팀, Platform 팀을 만들게 되었습니다.
Team Vision
오늘의집 모든 개발자의 Productivity를 향상 시키고, 코드 퀄리티를 올릴 수 있도록 도움이 되는 것
3. PoC(Proof of Concept)
API Gateway, Service Mesh 등 MSA를 만들어 가는 과정에서 필요한 다양한 플랫폼 요소들을 PoC하여, 적합한 기술 스택을 정하는 과정을 진행하고 있습니다. 각기 다른 경험을 해오신 시니어 개발자 분들의 의견과 리서치를 기반으로 후보군을 만들고, 각 기술에서 만족해야할 사항을 정리하여 테스팅을 진행하였습니다.
그 결과 API Gateway로는 Emissary-ingress를 선택하였고, Service Mesh는 아직 PoC 중이지만 Linkerd를 사용할 예정입니다. 또한, 서비스간의 internal 통신은 gRPC를 통해 이뤄질 것입니다. 해당 기술들을 선택하게 된 기준과 배경에 대해서는 Platform팀에서 정리하고 있으며 추후 공개할 예정입니다.
4. System, Service, Platform
오늘의집 서비스를 위해, 또 개발자들의 편의성을 위해 여러 가지 결과물을 만들어냈습니다.
- Auth Service: 서비스 간 일관된 인증을 보장하기 위한 서비스이며, OIDC도 지원하고 있습니다.
- Mortar System: 오늘의집 IDMS(Interface Definition Management System) 프로젝트 명이며, gRPC 통신을 하기 위한 여러 가지 메타정보의 라이프사이클을 관리해주는 시스템입니다.
- XPC: 다른 글에 실험 플랫폼으로 소개(클릭)되었지만, 데이터팀과 협업을 통해 진행했으며 단순 트래픽 컨트롤 기능도 제공하고 있습니다.
- OpsMonster: 지속적으로 변경되는 인프라에 맞춰서 운영 자동화를 하기 위해 만들었으며, 오늘의집을 구성하고 있는 여러 micro service들의 CMDB(Configuration Management Database)를 관리하는 시스템입니다.
- Log SDK: 추상화된 로그포맷을 서비스에 적용, 정규화된 로그 데이터를 Datadoghq으로 적재하여 분석 및 탐색을 용이하게 도움을 주는 라이브러리입니다.
각각의 서비스들에 대해선 XPC를 소개했던 것과 같이 각각 테마별로 소개하는 기회를 마련해보도록 하겠습니다.
5. 경험
위에서 말씀드렸듯이, 오늘의집에 훌륭한 개발자 분들이 많이 합류해 주셨습니다. 다른 환경에서 MSA 전환 프로젝트를 직접 진행해보신 분도 있고, 잘 되어있는 MSA 환경을 경험해본 분도 있습니다. 반대로 경험은 적지만 높은 실행력과 개발력을 갖춘 분들도 있습니다. 하지만 지금 새롭게 사용하고자 선택한 결과물을 통해 MSA 구성을 해본 경험은 모두에게 새로운 도전이었습니다. 또한, 가장 큰 문제로 Ruby on Rails와 React와의 강결합을 떼어내는 과업도 남아 있었습니다.
특정 인원을 배정해 일부 서비스를 나누면서 적용해 나가는 방법도 있지만, 이럴 경우 해본 사람만 계속하게 되고, 서로 다른 도메인 지식이 없어 진행에 어려움을 겪을 것이라고 생각되었습니다. 최대한 많은 개발자 분들이 실질적인 경험을 하여, 앞으로 장기적으로 진행되는 MSA 과업에서 보다 높은 이해를 가지고 적극적으로 프로젝트에 임할 수 있기를 바랬습니다.
이를 어떻게 할 수 있을까 고민하던 중 과감한 의견을 제안하였습니다. 2021년 말 중 3개월 간 프로덕트 개발을 멈추고 기술 과업에 몰두할 시간을 달라는 제안이었습니다. 모든 개발자를 MSA와 연관된 과업에 투입하여 프로젝트를 위한 기틀을 마련하는 한편, 팀 내에서 하나의 서비스에 대한 MSA를 진행함으로써 경험을 쌓는 시간을 마련하고자하였습니다. 그 결과 2021년 9월부터 12월 초까지 잠시 프로덕트 개발을 멈추고 2021년 11월 현재 모두 기술 과업에 몰두하고 있는 중입니다. 이 기간을 MSA Phase 1으로 부르기로 하였습니다.
MSA Phase1
Nov, 2021: In Progress
MSA Phase 1은 현재 진행 중에 있습니다. 해당 기간 내에 각 팀이 할 수 있는 범위를 산정하고 하나 하나 빌드업 해나가고 있습니다. 팀 간 의존 관계를 파악하여 끊고, 서비스 간 필요한 데이터 전달을 위한 작업을 진행 중입니다. Database에 대한 물리적 분리는 각 팀의 리소스에 따라 논리적 분리만 할 것이냐, 물리적 분리까지 진행할 것이냐를 선택하고 있으며 이를 통해 서비스 간의 직접적인 데이터베이스 참조를 막고 있습니다. 또한 위에서 잠시 언급한 Ruby on Rails와 React와의 강결합을 분리하기 위한, Backend/Frontend 분할 프로젝트를 마무리하고 QA 중입니다.
MSA 서비스 최초 런칭 원칙
MSA를 진행함에 있어 어떤 서비스든 최초에 만족해야 하는 조건이 있습니다. 서버의 Response가 변경될 경우 작업의 범위가 커지고, QA 기간도 오래 걸리기 때문에, 기존 서버와 새로 분리된 서버의 Response가 동일하게 반환되는지 확인하는 것을 원칙으로 하고 있습니다. 모든 기능에 대해서 QA를 진행하기 어려울 수 있기 때문에, 서버의 Response가 동일하게 떨어지는 것으로 새로운 서버 런칭 조건을 추가하였습니다. QA의 경우에는 QA팀에서 개발한 메인 시나리오에 대해 자동화 검증만 진행될 예정입니다. 최초 런칭 이후 API 단을 정리하는 것은 각 팀의 리소스에 맞춰 진행될 예정입니다.
Over the Phase 1
MSA 과업은 어느 정도 시간이 걸릴지 알 수 없으나 비즈니스와 프로덕트 요구사항을 충족하며, 완벽히 전환하기까지 3년에서 5년 정도의 시간이 걸릴 것으로 예상하고 있습니다. 또한 10x를 목표로 잘 준비했다 하더라도, 앞으로 서비스가 성장함에 따라 다시 아키텍처링 해야하는 부분이 새롭게 나올 수도 있습니다. 앞으로 각 분야에서 각 팀에서 어떻게 준비하고, 어떤 문제를 풀어내면서 MSA 전환 프로젝트를 진행하는지 지속적으로 소개될 예정입니다. 많은 관심 부탁드립니다.
오늘의집은 No.1 Lifestyle Tech Company라는 비전을 달성하기 위해, 더 빠르고 정교하게 라이프스타일 시장에서 겪고 있는 다양한 문제를 우리가 쌓아올린 기술과 프로덕트를 통해 해결해낼 것입니다. Phase 1이 끝난 후에는 각 팀 내에서 리소스를 분할하여 서비스 개발과 MSA 분리를 점진적으로 해나가며 기술을 계속 쌓아 나갈 것입니다. 이 과정 속에서 사용자의 다양한 문제 그리고 기술적 문제들을 함께 해결해 나갈 많은 개발자 분들을 찾고 있습니다.