인프콘 2022 - 인프런 아키텍처의 과거와 현재, 그리고 미래
부제: 적정 소프트웨어 아키텍처 (현실과 이상 사이 어딘가?)
인프런 아키텍처의 과거와 현재, 그리고 미래
부제: 적정 소프트웨어 아키텍처 (현실과 이상 사이 어딘가?)
시즌 1
- 자금과 동료가 없음(극초창기 스타트업) → 대표 혼자 모든걸 개발
- 직접 개발은 최소화하고 외부 자원을 적극활용(SaaS)
- JQuery, PHP, WordPress, MySQL로 회원수 10만까지 버텼으나 한계가 느껴짐
시즌2
- 개발자를 채용하여 SaaS를 걷어내고 모든 서비스를 다시 개발함 (BE1, FE1, DevOps1, 대표1)
- BE = Java, FE = TS, DevOps = Go 등으로 기술 스택이 다양해지면 어느 분야 개발자가 단 한명이라도 빠질 경우 전체 개발 진행이 안되는 아주 큰 리스크가 존재함
- 따라서 모든 직군의 기술 스택을 JS로 통일하였음
- 3.5(0.5명은 대표님)명의 개발자가 5개월동안 전체 시스템을 워드프레스 → JS로 전환에 성공
- JS로 변경 후 문제
- 코드만 봐서는 함수가 어떤 값을 반환하는지 알 수 없음
console.log
와디버그 모드
를 활용해 코드를 파악해야만 함- 테스트 코드를 작성하기가 불가능에 가까움
- IDE의 도움을 받기가 힘듬(인터프리터 언어의 한계?)
- BE와 FE가 싱글 레포에서 모두 관리되었음
- FE를 수정해도 BE까지 영향이 감
- BE를 수정해도 FE까지 영향이 감
- Bundling, Reload 속도가 참을 수 없을정도로 느려짐
- 신규 입사자들이 기존의 코드를 이해하기가 점점 어려워짐
시즌3
- 개발자들이 코드 수정에 자신감이 생기도록 개선해야함
- 테스트 코드, 정적분석 등을 도입
- 신규 입사자들의 진입장벽이 낮아지도록 메이저한 라이브러리, 패턴등을 사용하기로 함
- 언어를 TS로 변경
- FE =
React
,Next.js
를 도입 - BE =
Nest.js
&TypeORM
도입 Layered Architecture
와DI
도입- FE, BE를 분리하여 서로 독립적으로 개발 할 수 있게끔 하기로 함
- 어떻게 할 것인가?
빅뱅
- 서비스 개선을 중단하고 전체를 다시 만들어서 한번에 교체 → 약 1년 예상
점진적 개선
- 서비스 개선과 시스템 개편을 병행 → 약 2년 예상
- 서비스 성장속도가 가팔랐음(매년 약 200~300%)
- 회사의 압축 성장을 가속화 해야 하기 때문에 서비스를 중단 하기가 어려웠음
교살자 패턴
으로 서비스를 개선하기로 함. 즉, 점진적 개선 (달리는 마차의 바퀴를 갈아끼운다)
- FE, BE 모노 레포를 신규로 생성하고 기존 코드를 점진적으로 이관 시키려 함
통합 IAM 시스템
을 분리 개발 →API Gateway
도입
- 모든 계획을 짜고 코드 이관 작업을 시작
- 3일동안 매일 2시간씩 서버가 죽는 장애가 발생
- 한 기능의 작은 장애가 전체 시스템의 장애로 전파되기 시작함
시즌4
- 개발팀 구성
- BE 8
- FE 11
- DevOps 4
- CTO 1
- 장애
- 어드민에서 ROW 50,000 정도의 엑셀을 다운받았더니 전체 시스템이 다운되는 경우도 발생
- 독립적으로 운영되는 서비스들을 분리하기로 결정하고 실행
- 서버의 메모리, CPU를 많이 점유하는 작업으로 인한 장애는 격리됨
- 하지만
단일 RDB 구조
로 인한 장애는?- 분산 DB까지 도입하면 시스템 복잡도가 너무 크게 늘어남
- 트랜잭션 관리가 매우 어려워짐
- 기존 쿼리들도 모두 개선해야함
- 지금 못하니까 시즌5에 하도록 하자
- 집중
- 시스템 복잡도를 극한으로 최소화
- (구)인프런 레거시 개편
- 레거시 개편하며 발생하는 장애 트러블 슈팅
- 다양한 신규 요구 사항 커버
- 기술 스택을 컴팩트하게 가져가 관리 포인트를 최대한 줄이자 (안 그래도 해야할게 많다)
MongoDB Atlas
로 검색엔진, Data Lake, 실시간 데이터 등을 모두 처리 (최소 2~3년만 DB 장애 안나게 버티면서 다른거에 집중해보자)
- 서비스 구조
- (구)인프런
- (신)인프런
- 통합 IAM
- AWS SNS를 도입 → 멀티 구독
- AWS SQS로 최종적인 일관성을 보장
- Spring Boot를 도입하고 Back Pressure를 이용해 서버가 다운 되지 않게 대용량 데이터를 핸들링
🔔 Back Pressure ?
: 클라이언트가 서버에 자신이 감당할 수 있는 만큼만 요청해서 처리할 수 있게 해주는 기술을 말한다. 한국어로는배압
또는배압 조절
로 번역되고 있으며 자바 진영에서 이러한 기술의 구현을 위한 스펙이리액티브 스트림
이다. 그리고, 이 스펙의 구현 중 하나가 그 유명한리액터
이고 스프링에서는 리액터를 사용해웹 플럭스
를 구현했다.
- 서버 → AWS SNS로 이벤트 발행이 실패하면?
- 이벤트 저장소를 중간에 두면 쉽게 해결할수는 있다
- 단, 시스템 복잡도가 너무 높아짐
- 이번 시즌에는 이벤트 발행이 실패하면 로그를 확인해 수동으로 재 발행 하기로 결정
- 현재는 시스템 복잡도를 최소화하고 (구)인프런을 모두 걷어내는데에 집중하고 있음
- 완벽한 시스템을 최초에 단번에 만들어 낼 수는 없다
- 시스템을 수시로 모니터링하며 점진적으로 고쳐 나간다
나의 Q&A
우리 회사는 현재 시리즈 B에서 누적 330억 규모의 투자를 받아 다음 라운드를 준비하고 있고, 파이썬 2.7로 된 레거시를 자바로 마이그레이션 하는 작업을 진행하고 있다. 하지만 서비스 개선 작업시 기존 레거시에 대부분의 리소스를 점유당하고 있다. 복잡하게 얽힌 의존성과 매우 나쁜 가독성으로인함이다. 상황이 이러하니 이 세션내내 내가 현재 재직중인 회사의 상황과 굉장히 비슷해서 매우 몰입하며 들었고, 대부분의 내용도 공감됐다.
세션이 종료된 후 나는 세션 발표자인 이동욱(인프런 CTO)
님께 다음과 같은 질문을 드렸고, 다음과 같은 답변을 들었다.
Question
: 우리 회사도 파이썬으로 된 레거시 시스템을 자바로 옮기고 있는데, 파이썬이라는 언어 자체가 잘못된 함수 호출을 막을 수가 없다. 또한 코드만 봐서는 함수에 어떤 값이 입력되고 어떤 값이 리턴되는지 알 수가 없기 때문에 코드를 파악하기 위해 print 함수
와 디버그 모드
를 활용해야만 한다. 무엇보다 테스트 코드를 작성하기가 너무 어렵다. 내가 생각하기엔 JS도 이와 크게 다르지 않을 것 같은데 어떻게 코드를 이관하고 있는지?
Answer
: JS역시 비슷하다. 테스트 코드를 완벽하게 작성하기가 불가능에 가깝다. 따라서 우리는 각 엔드 포인트마다 성공하는 케이스에 대해서만 테스트 코드를 작성하고 장애를 맞아가면서 강제로 코드를 옮겼다. 아마 파이썬도 크게 다르지 않을 것이라고 생각한다.