당근 커뮤니티실이 2021년 약 100 RPS에서 현재 약 20,000 RPS를 처리하는 규모로 성장한 과정과, 이를 가능하게 한 "여러 웹앱 + 하나의 서버앱" 모듈형 모놀리스 아키텍처를 다룬다. 동네생활, 모임, 카페, 아파트 서비스를 소규모 팀이 장기 운영 가능한 구조로 설계한 원칙과, 장애 경험에서 도출한 resilience 패턴까지 단계별로 정리했다.
핵심 포인트- 100 RPS → 4,000 RPS → 20,000 RPS 성장에도 모듈형 모놀리스를 유지한 이유는 한 코드베이스에서 도메인 변경 추적, 트랜잭션 조율, 소규모 팀의 지속 운영이 가능하기 때문이다.
- 서버앱을 API(응답 시간), Worker(처리량·적체), Batch(스케줄 1회 실행), Console(운영자 도구) 4가지 실행 단위로 분리해 각 트래픽 특성에 맞게 운영한다.
- OpenAPI 계약을 중앙 저장소에서 관리하고 Kotlin 서버 스텁과 TypeScript 클라이언트를 자동 생성해, CI에서 하위 호환성을 자동 검사한다.
- 게시글 작성 시 본문·투표·해시태그는 동기 트랜잭션으로 처리하고, 검색 색인·임베딩·알림은 비동기 이벤트로 격리해 한 작업 실패가 다른 작업을 막지 않는다.
- 장애 대응이 초기 DB CPU 100% → 커넥션 풀 소진/JVM 메모리 누수 → 시스템 간 상호작용 장애 순으로 복잡해졌고, 단계마다 회로 차단기·요청 취소·폴백·선제 스케일링을 추가했다.
상세 정리- 규모 변화: 2021년 가을 약 100 RPS로 시작, 당근모임 전국 오픈 시 약 4,000 RPS, 현재 약 20,000 RPS를 처리한다.
- 아키텍처 선택 기준: 마이크로서비스를 지양한 게 아니라 "누가 이것을 관리하고 운용할 수 있는가"를 기준으로 모듈형 모놀리스를 선택했다.
- 웹 계층 진화: CSR → SSR → Streaming SSR로 점진적으로 개선했다. Streaming SSR은 API 없이 뼈대를 먼저 송신하고 이후 콘텐츠를 스트리밍하며, 타임아웃 시 CSR로 자동 폴백한다.
- 서버앱 4분류: API(사용자 요청, 응답 시간 중심), Worker(이벤트 기반 후속 작업, 처리량·적체 모니터링), Batch(스케줄 작업, 프로세스당 1회 실행 후 종료), Console(운영자 도구, 트래픽 분리) 로 실행 단위를 구분한다.
- 데이터 계층: Amazon RDS(PostgreSQL)을 원본으로, Valkey(Redis 대체)·로컬 캐시 조합, RabbitMQ(내부 메시징), Kafka(전사 연계), OpenSearch(파생 조회 모델)를 사용한다.
- 모듈화 원칙: "같은 이유로 바뀌는 코드를 묶고, 다른 이유로 바뀌는 코드를 나눈다." 도메인 규칙·데이터 접근·인프라를 별도 모듈로 분리하고 모듈 간 의존은 인터페이스만 허용한다.
- OpenAPI 계약: 중앙 저장소에서 API 계약을 관리하고 Kotlin 서버 스텁과 TypeScript 클라이언트를 코드 생성한다. CI에서 하위 호환성을 자동 검사해 "명세와 구현이 어긋날 가능성을 줄인다".
- 이벤트 격리: 게시글 작성 시 본문·투표·해시태그·장소·구독 상태는 동기 트랜잭션, 검색 색인·임베딩 생성·콘텐츠 검수·배지 발급·알림은 비동기 이벤트로 분리해 실패 격리를 달성한다.
- 피드 조립 흐름: 후보 목록 구성 → 추천 엔진 정렬 → 노출 정책 적용 → 카드 조립 순으로 진행하며, 추천 실패 시 기본 순서, SSR 실패 시 CSR로 폴백한다.
- 아키텍처 테스트: 모듈 간 의존 방향을 자동으로 검사하고 "기준선 기법(기존 위반 동결, 새 위반만 차단)"으로 레거시와 신규 코드를 구분해 관리한다.
- 장애 단계별 진화: 초기에는 문제 쿼리로 DB CPU 100%, 확장 단계에서는 커넥션 풀 소진과 JVM 버전업 후 메모리 누수, 고도화 단계에서는 검색 부하·웹앱 재시도 증폭·미완료 요청 누적 같은 시스템 간 복합 장애로 진화했다.
- Resilience 도입: 요청 취소(cancellation), 폴백, 회로 차단기(circuit breaker), 기능 제어, 선제 스케일링을 차례로 도입해 고도화 장애에 대응했다.
- 컴포넌트 공통화 원칙: 위치 정보·투표·임베딩 등 공통 기능은 "두 번째 사용처가 생겼다는 이유만으로 곧바로 공통화하지 않는다"는 원칙 하에 신중하게 추출한다.
- 향후 방향: 화면 단위 API에서 리소스 중심 API로 전환해 웹앱이 조립 책임을 가져가는 구조, AI 기반 콘텐츠 플랫폼 구축, 더 작은 단위 검증·빠른 배포·빠른 롤백 체계 3가지를 과제로 제시했다.
왜 읽나20,000 RPS 규모까지 모듈형 모놀리스를 소규모 팀으로 5년간 운영한 당근의 아키텍처 결정·장애 대응 경험을 단계별로 볼 수 있어, 서비스 성장에 따른 시스템 설계를 고민하는 백엔드·아키텍처 엔지니어에게 유용하다.