당근페이 백엔드 아키텍처, 계층형에서 모노레포까지의 여정

by DD
4개월 전
조회수 576

당근페이 백엔드는 계층형 아키텍처(Layered Architecture)로 시작하여 서비스 확장에 따라 코드 복잡도 증가(Code Complexity) 문제를 겪음

헥사고날 아키텍처(Hexagonal Architecture) 도입으로 비즈니스 로직과 외부 구현을 분리하고, 유지보수성(Maintainability) 및 테스트 용이성(Testability) 확보

클린 아키텍처(Clean Architecture)모노레포(Monorepo)로 전환하여 도메인별 모듈 분리, 배포 독립성(Deployment Independence) 및 개발 생산성 향상

모노레포 도입 후 코드 라인 증가에도 불구하고, 빌드 속도 개선(Build Speed Improvement)을 통해 개발자 경험(Developer Experience) 유지

지속적인 아키텍처 개선을 통해 금융 서비스의 안정성(Stability) 및 비즈니스 임팩트(Business Impact)를 극대화

계층형 아키텍처(Layered Architecture)의 한계와 헥사고날 아키텍처(Hexagonal Architecture) 도입 배경

당근페이는 초기 계층형 아키텍처(Layered Architecture)를 채택하여 빠른 개발을 추구했지만, 서비스 확장에 따라 코드베이스의 복잡도가 증가했다. 특히, Service 계층 간의 강한 의존성으로 인해 코드 변경(Code Change) 시 영향 범위를 예측하기 어려워지고, 테스트 및 리팩터링(Refactoring)의 어려움이 발생했다. 이러한 문제점을 해결하기 위해 당근페이팀은 헥사고날 아키텍처(Hexagonal Architecture)를 도입했다. 헥사고날 아키텍처는 애플리케이션 핵심 로직과 외부 구현을 명확히 분리하고, 포트를 통해 의존성을 연결함으로써 잘못된 의존성(Wrong Dependency)을 방지하는 데 초점을 맞췄다.

헥사고날 아키텍처(Hexagonal Architecture)의 Money 2.0 구조

헥사고날 아키텍처(Hexagonal Architecture)를 적용한 Money 2.0 구조는 domain, usecase, adapter 세 가지 모듈로 구성되었다. Domain 모듈은 당근머니 지갑의 입금과 출금 같은 핵심 규칙을 정의하며, 외부 기술에 의존하지 않는 POJO(Plain Old Java Object)로 구성된다. Usecase 모듈은 송금, 충전, 환불 등 사용자 시나리오 단위로 응집하며, 트랜잭션 경계, 검증, 도메인 정책 조합, 포트 호출을 책임진다. Adapter 모듈은 domain 모듈에서 정의한 인터페이스를 구현하며, 데이터베이스, 메시지 브로커, 외부 API 호출 등을 담당한다. 이러한 구조를 통해 비즈니스 로직과 기술적 세부 사항을 분리하고, 코드 재사용성(Code Reusability)과 유지보수성을 향상시켰다.

모노레포(Monorepo) 도입을 통한 도메인 분리 및 배포 독립성 확보

헥사고날 아키텍처(Hexagonal Architecture) 적용 이후에도, 여러 도메인이 하나의 프로젝트에 공존하면서 발생하는 문제점이 있었다. 특히, Adapter 모듈에 불필요한 의존성이 추가되고, 서비스와 무관한 코드 변경이 배포되는 문제가 발생했다. 이러한 문제를 해결하기 위해 당근페이팀은 클린 아키텍처(Clean Architecture)를 기반으로 한 모노레포(Monorepo)를 도입했다. 모노레포는 도메인별 모듈 분리, 의존성 역전, 배포 독립성, 테스트 용이성을 목표로 하며, 각 서비스의 독립적인 배포(Independent Deployment)를 가능하게 했다. 그 결과, 머니 송금 유스케이스의 변경 사항이 다른 서비스에 영향을 미치지 않게 되었다.

모노레포(Monorepo) 환경에서의 개발 생산성 향상

모노레포(Monorepo) 도입은 개발 생산성 향상에 기여했다. 새로운 애플리케이션 구성에 필요한 보일러플레이트를 제공하는 도구를 통해, 엔지니어는 버튼 한 번으로 초기 코드베이스를 완성할 수 있게 되었다. 코드 라인 수 증가에도 불구하고, 팀은 빌드 속도 개선에 지속적으로 노력하여 엔지니어가 체감하는 빌드 소요 시간을 유지했다. 이러한 노력은 작은 변경의 잦은 릴리즈를 가능하게 했고, 피드백 루프(Feedback Loop)를 가속화하여 비즈니스 임팩트를 빠르게 만들어내는 결과를 가져왔다. 또한, 코드 리뷰(Code Review)를 통해 설계 의도를 공유하고 서로 배우는 문화를 조성하여 팀 전체의 기술적 성숙도(Technical Maturity)를 향상시켰다.

모노레포(Monorepo)의 장점과 지속적인 개선 노력

모노레포(Monorepo)는 코드베이스의 일관성을 높이고, 문제 해결 시간을 단축하는 데 기여했다. A 서비스와 B 서비스 간의 타임아웃 설정, 의존성 관리, 린트, 테스트, 빌드, 배포 기준 등을 모노레포(Monorepo)를 통해 일관되게 관리할 수 있게 되었다. 또한, 런북(Runbook)을 자동화하여 장애 대응 역량을 강화했다. 당근페이팀은 모노레포의 장점을 극대화하기 위해, 코드베이스 관리, 개발자 경험(Developer Experience) 개선, 그리고 문화 확산에 대한 지속적인 고민을 이어가고 있다. 이러한 노력은 금융 서비스의 안정성(Stability)을 높이고, 팀의 지속적인 성장(Continuous Growth)을 가능하게 하는 원동력이 될 것이다.

당근페이 백엔드 아키텍처가 걸어온 여정