599. 모듈러 모놀리스 (Modular Monolith) 아키텍처 - MSA 전환 전 단계, 모듈 간 강결합 방지 아키텍처
핵심 인사이트 (3줄 요약)
- 본질: 모듈러 모놀리스(Modular Monolith) 아키텍처는 "트래픽 쥐꼬리인 스타트업이 무지성 힙스터병에 걸려 마이크로서비스(MSA) 50개 찢기 도입했다가 서버 인프라 요금과 핑(Ping) 렉 지옥으로 파산하는 병신 짓"을 막아내는 구원투수로, 물리적으로는 1대의 싸구려 톰캣(Tomcat) 서버 뱃속에 통째로 올려 1초 컷 배포(Monolith) 꿀을 빨면서도, 소스코드 구조는 MSA처럼 칼같이 찢어두는(Modular) 극강의 모순 극복 타협점이다.
- 가치: 1대의 JVM 메모리 안에 코드가 다 같이 살아있지만, 아키텍트가 멱살을 잡고
주문 패키지가결제 패키지의 1. Java 클래스를 직접 호출하지 못하고(의존성 분리), 2. 결제 DB 테이블을JOIN치지 못하게 강제 락(Lock)을 걸어버림으로써 모놀리식의 스파게티 강결합 똥 코드를 원천 차단해 낸다.- 융합: 이 뼈대를 구축해 두면 초기엔 돈 한 푼 안 들고 로컬 트랜잭션 1방(ACID)으로 편하게 꿀을 빨다가, 2년 뒤 1,000만 트래픽 터지며 진짜 서버를 찢어야 할 순간이 오면! 코드 리팩토링 1도 없이 걍 엑셀 찢듯 폴더(Module)만 복붙 컷오프(Cut-off)해서 1시간 만에 완벽한 MSA 우주로 텔레포트(Migration) 쳐버리는 인류 최고의 클라우드 1티어 대피소(Exit Strategy)다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
-
개념:
- Monolith (모놀리스): 배포(Deployment) 단위. 웹서버, DB 연결, 스케줄러 모든 기능 1,000만 줄을 거대한
.jar압축 깡통 딱 1개로 말아서 AWS 서버 1대에 통째로 던져 올리는 구식의 위대한 가성비. - Modular (모듈러): 소스코드(Code) 단위. 비록 압축 파일 1개 안에 쑤셔 넣어지지만, 소스 코드 패키지(
order,payment) 간에는 콘크리트 벽(Interface/Event)을 세워 서로 남의 살림살이(DB, 변수)를 함부로 훔쳐보거나 만지지 못하게 완벽히 분업 격리 쳐두는 우아한 객체 지향 상태.
- Monolith (모놀리스): 배포(Deployment) 단위. 웹서버, DB 연결, 스케줄러 모든 기능 1,000만 줄을 거대한
-
필요성 (무지성 MSA병 척결과 스타트업의 눈물): 창업 첫날. 주니어가 "요즘 쿠팡은 무조건 MSA지 ㅋ" 라며 주문 서버, 배송 서버를 도커 파드(Pod) 10개로 찢어버렸다. 하루 접속자 100명인데, 이 파드 10개가 1개의 결제를 처리하려 서로 K8s 카프카(Kafka) 네트워크를 타고 핑퐁 통신을 치느라 Ping 타임아웃 지연(Latency)이 3초 터지고, 분산 트랜잭션(Saga 패턴 환불 로직, 550장) 짠다고 코드는 10배 길어져 개발자 3명이 과로로 다 뻗어 퇴사했다. 스타트업 런칭 1달 만에 클라우드 K8s 요금 1,000만 원이 찍히며 파산했다. "아 씨발! 일단 돈 없을 땐 가볍게 1통짜리 톰캣 서버 1대 띄워서 로컬 통신 1초 컷으로 개꿀 빨리 런칭 치고 싶은데! 나중에 트래픽 터졌을 때 똥 코드 스파게티 걷어내느라 1년 재개발하는 건 막을 꼼수 없을까?!" 이 피눈물 나는 스타트업 대표들의 탐욕이 모듈러 모놀리스를 천하 통일의 교과서로 빚어냈다.
-
💡 비유: 쌩 모놀리스(스파게티)는 **'거대한 원룸 고시원(1통짜리)'**입니다. 10명(코드)이 파티션 하나 없이 엉켜 살아서 누가 똥(에러) 싸면 원룸 전체 100% 냄새 다 퍼지고 죽습니다(강결합). 무지성 MSA는 **'강남 아파트 10채 사서 1명씩 분가시킨 짓'**입니다. 쾌적하긴 개뿔, 친구(다른 서버) 만나서 밥 한 번 먹으려면 매번 차 끌고 30분씩 톨게이트(네트워크 API 지연) 타야 하고 월세(AWS 서버비) 터져서 길거리에 나앉습니다. 모듈러 모놀리스는 '100평짜리 거대 단독 주택 1채(모놀리스 서버 1대)' 안에 철저하게 방 10개를 콘크리트 방음벽(모듈 캡슐화)으로 나누어 지어둔 것입니다. 월세(서버비)는 1채 값만 내는 극한 가성비 꿀을 빨고, 거실 문(인터페이스)만 열면 1초 컷 핑퐁 통신(로컬 메소드 호출)으로 초광속 대화가 가능하면서도! 철수가 자기 방(모듈)에서 불장난(에러)을 쳐도 절대 영희 방으로 번지지 않는 궁극의 가성비+무결점 펜트하우스입니다.
-
등장 배경 및 발전 과정:
- Monolithic Hell (2000s): JSP 파일 1개에 DB 쿼리, 화면, 결제 로직 1만 줄이 비빔밥 된 스파게티 지옥 시대. 서버 띄우는 데 10분 걸림.
- Microservices Hype (2015~): 넷플릭스 뽕을 맞고 전 세계 모든 개발자가 "무조건 쪼개는 게 정답!" 이라며 50개 파드로 찢었다가, 네트워크 분산 트랜잭션의 난이도 지옥에 빠져 수만 개 스타트업 멸망.
- "Monolith First" 선언 (현재): 마틴 파울러 아저씨가 일침을 놨다. "니들 트래픽 쥐꼬리면서 왜 찢고 깝침? 무조건 모놀리식으로 시작해라(Monolith First)! 대신 코드 내부 패키지 뼈대만 완벽하게 도메인 단위로 썰어놔(Modular)! 그리고 100만 트래픽 터질 때만 그때 가서 칼로 툭 잘라서 MSA로 이사 가라 ㅂㅅ들아!" 대 오답 노트의 시대.
-
📢 섹션 요약 비유: 모듈러 모놀리스 뼈대는 **'비상 탈출용 캡슐이 10개 장착된 거대 우주 모선(Mothership)'**과 똑같습니다. 평소엔 엔진 1개(서버 1대)로 우주를 미친 듯이 빠르게, 가성비 쩔게 항해합니다(Monolith). 하지만 적의 포탄을 맞아 엔진에 과부하가 걸려 모선이 터지려 하는 그 찰나의 폭발 임계점(Traffic 폭주 1,000만)! 아키텍트가 비상 버튼 하나를 누르면, 붙어있던 10개의 캡슐(모듈)이 찰칵찰칵 0.1초 만에 몸체에서 뜯겨 나가며 10대의 독립 우주 전투기(MSA 파드 분산)로 변신해 우주 사방으로 찢어져 흩날리며 100배의 공격력을 퍼붓는, 가장 완벽한 2단 진화 트랜스포머 생존술입니다.
Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)
1. 모듈을 찢어 죽이는 3대장 강철 헌법 (Decoupling Rules) 💥
1대의 톰캣(JVM) 안에서 이 3가지를 못 지키면 그건 모듈러가 아니라 걍 스파게티 똥이다.
① 도메인(모듈) 간 DB 테이블 쌩(Raw) JOIN 절대 금지! 💥💥
- 똥 코드:
주문 모듈이결제 테이블이랑 조인 쳐서SELECT * FROM order A JOIN pay B1방 쿼리로 긁어옴. (DB 레벨 강결합 대참사). 나중에 결제 파드 딴 서버로 찢는 순간 조인 쿼리 다 터져서 회사 망함. - 방어: DB가 1개(Oracle 1대)여도,
주문 엑셀이랑결제 엑셀은 다른 우주에 있다고 세뇌(Logical DB Separation)해라! 주문 로직이 결제 데이터 필요하면? 무조건 자바 코드 메모리 위에서 결제 모듈이 뚫어놓은 공식 API(Java 함수)payService.getPayInfo(orderId)를 호출(Call)해서 자바 객체로 데이터를 던져받아 메모리 안에서 합쳐라! (이래야 나중에 결제가 딴 서버로 날아가면 저 함수 1줄만 HTTP REST API 호출로 쓱 바꾸면 1시간 컷 이사 끝이다).
② 모듈 간 통신은 무조건 '인터페이스(Interface) 껍데기'와 '이벤트(Event)'로만!
- 똥 코드: 주문 로직 안에서
new PayServiceImpl().doPay()쌩 하드코딩 객체 생성. - 방어 1 (Interface): 주문 모듈은
PayInterface라는 빈 껍데기(명세서)만 쳐다봐야 한다. (DI/IoC 의존성 역전 586장 융합). - 방어 2 (Event 기반 비동기 👑): 결제가 끝나면 "야 알림톡 쏴!"라고 알림 모듈을 다이렉트로 찌르지 마라! 스프링의
ApplicationEventPublisher(로컬 인메모리 이벤트 버스) 허공에다가"결제 완료됨 ㅋ"텍스트 쪽지 1장 던지고 걍 끝내라(Fire and Forget). 알림 모듈이 알아서 그 쪽지 줏어먹고 메일 날린다. (나중에 딴 서버로 찢을 땐 저 로컬 쪽지 통을Kafka로 텍스트 1줄만 스위칭 치면 무결점 분산 비동기 100% 텔레포트 완성이다!!).
③ 코드 패키지(Package/Module)의 양방향 핑퐁 참조 금지 (Cyclic Dependency)
주문이결제를 참조(import)하는데,결제코드 위에서 আবারimport 주문을 친다? 자바 켜자마자 스프링 빈(Bean) 순환 참조 폭발로 서버가 즉사한다. 무조건 의존성 화살표는A ➡ B ➡ C단방향 폭포수(DAG)로만 깎아내려 가야 한다.
2. 컴파일 타임(Compile-time)의 멱살잡이: ArchUnit 도입 💥
말(매뉴얼)로 "야 남의 모듈 찌르지 마!" 해봤자 주니어들은 귀찮아서 100% 찌른다. 기계가 패야 한다.
-
원리: 엑셀 1통짜리 서버니까 컴파일 에러도 안 나고 몰래 남의 패키지
import쳐서 스파게티 똥 싸는 걸 막을 물리적 방법이 없다. 아키텍트는 TDD 테스트 봇(ArchUnit)을 젠킨스(CI) 파이프라인에 쾅! 박아둔다. -
검사 룰:
@AnalyzeClasses(packages = "com.coupang")➡ 봇이 바이트코드를 싹 훑어본다. "어?order패키지 놈이 감히payment패키지의 내부 숨겨진 로직(Impl)을 불법으로import쳤네?! 즉시 빌드 컷오프(Build Failure) 빨간불 시뻘겋게 띄워버리고 배포 셧다운 시켜!!!" -
결과: 개발자의 얄팍한 꼼수(Tight Coupling)를 코드 리뷰 인간의 눈이 아니라 기계의 잔혹한 컴파일 차단기 쇠고랑으로 1초 컷 봉쇄해 내는 궁극의 인프라적 캡슐화 강제 통치술이다.
-
📢 섹션 요약 비유: 이 ArchUnit 통제는 **'회사 사옥 부서 간 유리벽과 지문 인식기'**입니다. 1개의 100평짜리 1통 건물(모놀리스)을 쓰지만, 기획팀(주문 모듈)과 재무팀(결제 모듈) 사이엔 투명한 방음벽이 쳐져 있습니다. 기획팀 신입이 귀찮다고 재무팀 방에 몰래 문 열고 들어가서 장부(DB) 훔쳐보려 시도(강결합)하는 순간!! 문 손잡이에 달린 **지문 인식기(ArchUnit 봇)**가 "삐빅! 권한 없음! 퇴사!!" 시뻘건 사이렌을 울리며 발목을 분질러버립니다. 1건물에 살아도 무조건 정식 '문서 수발실(인터페이스 API)' 구멍을 통해서만 대화하게 만드는 무자비한 룰 통치입니다.
Ⅲ. 융합 비교 및 다각도 분석
1. 백엔드 아키텍처 3단 진화 폼 최후의 요약 (Spaghetti vs Modular vs Microservices)
아키텍트 면접에서 "우리 회사 인프라 전략 세워보세요" 할 때 꺼내는 절대 헌법.
| 척도 | 1. 쌩 모놀리식 (스파게티 똥) 🪨 | 2. 모듈러 모놀리스 (Modular Monolith) 👑 | 3. 마이크로서비스 (MSA 50개 찢기) 🚀 |
|---|---|---|---|
| 코드 구조 | 1개 폴더에 모든 컨트롤러/서비스 우다다 박아둠. | order, pay 패키지(모듈)로 뼈대 완벽히 칼같이 찢어둠. | 아예 깃헙(Git) 저장소(Repo) 자체가 50개로 남남으로 찢어짐. |
| 물리적 서버 | AWS EC2 1대 (Tomcat 1대) | AWS EC2 1대 (Tomcat 1대 띄우는 건 똑같음 ㅋ) | AWS K8s 파드(Pod) 50대로 산산조각 파편화. |
| 통신 렉(Ping) | 로컬 RAM 0.001초 컷 | 로컬 RAM 0.001초 컷 (돈 한 푼 안 들고 개빠름 극강 효율) | K8s 네트워크 타느라 통신당 왕복 100ms 지연 및 타임아웃 지옥 터짐. |
| 트랜잭션(롤백) | DB 1개라 Rollback 1줄 컷 | DB 1개라 Rollback 1줄 컷 (우주 최강의 편안함) | DB 50개라 Saga 패턴(550장) 비동기 환불 코드 생코딩 치다 다 뻗음. |
| 아키텍트 픽 | 당장 낼모레 해커톤 내야 할 때. | 신규 스타트업 B2C 서비스 런칭 시 우주가 두 쪽 나도 무조건 0순위 베이스 픽. | 일 트래픽 100만 넘어가고 개발자 100명 넘어서 깃헙(Git) 충돌 터질 때 찢는 마지막 동아줄. |
과목 융합 관점
-
클라우드 / 트래픽 확장성 (Scale-out 의 치명적 한계 딜레마): 모듈러 모놀리스의 유일한 아킬레스건이다. 쇼핑몰에 트래픽이 10만 터졌다! 근데 10만 트래픽 중 90%는 "상품 검색(Search)"이고, 결제(Pay)는 1%밖에 안 한다 쳐보자. K8s 오토스케일링 봇(HPA)은 멍청해서 모놀리스 1통짜리 뚱뚱한 2GB 톰캣 컨테이너를 통째로 100대(200GB)로 수평 복제(Scale-out)해 버린다!! 정작 바쁜 건
Search부품 1개뿐인데, 안 바쁜Pay,Review부품 쓰레기들까지 덩달아 100개로 무식하게 복제 펌핑되며 AWS 메모리 램(RAM) 서버비를 매달 1억 원씩 태워 먹는 돈지랄 파탄이 열린다. 이 "부품별 부분 다이어트 스케일업 불가능"이라는 돈 터지는 임계점을 마주하는 순간, 그날 밤 아키텍트는 당장 도끼를 들고 가장 트래픽을 많이 처먹는Search 모듈딱 1덩어리만 핀셋으로 도려내어 밖으로 MSA 파드로 찢어 발겨 텔레포트(Extraction) 시키는 수술실 집도를 치러야 한다. (이게 MSA 전환의 정석이다). -
데이터베이스 공학 (폴리글랏 퍼시스턴스의 박탈): 533장의 꽃, "검색은 Elasticsearch, 결제는 Oracle, 장바구니는 Redis!" 이 멋진 다중 DB 골라 먹기를 모놀리스에선 쓰기 개빡세다. 하나의 통짜 톰캣 서버에서 DB 드라이버 5종류 다 물고 5개의 커넥션 풀을 켜두면 서버 메모리가 초기 부팅부터 OOM(Out of Memory) 터져 즉사한다. 모놀리스 시절엔 눈물을 머금고 거대 Oracle/MySQL 1통짜리 RDBMS에 검색이든 결제든 꾸역꾸역 100% 때려 박는(Single DB Bottleneck) 모래주머니를 차고 뛰어야 하는 숙명적 트레이드오프(Trade-off)가 강제된다.
-
📢 섹션 요약 비유: 모듈러 모놀리스의 스케일링 딜레마는, **'팔 근육만 키우고 싶은데 무조건 전신을 살찌워야 하는 마인부우'**와 같습니다. 오른쪽 팔(상품 검색 트래픽)만 바빠서 팔 근육만 10배로 키우고 싶은데, 하나로 붙어있는 통짜 몸뚱이(모놀리스)라서 몸 전체에 햄버거 100개(오토스케일링 메모리 폭발)를 쑤셔 넣어 억지로 거인(AWS 요금 떡상)을 만들어야 합니다. MSA 찢기는 이 거인의 오른쪽 팔(검색 모듈)만 칼로 툭 썰어내어(Offloading) 밖으로 던진 뒤, 그 잘라낸 팔 1개만 미친 듯이 100개로 복제 배양시켜 요금을 1/100로 후려치는 궁극의 파츠 다이어트 술법입니다.
Ⅳ. 실무 적용 및 기술사적 판단
실무 시나리오
-
시나리오 — 'DB 스키마 강결합(Schema Coupling)' 꼼수로 인한 MSA 이사(Migration) 대실패기: 3년 동안 모듈러 모놀리스(Java 패키지 찢기)로 예쁘게 코드를 잘 관리했다! 트래픽이 터져서 드디어 "결제 패키지"를 밖으로 MSA 서버로 찢으려고 코드를 폴더째로 잘라 새 Git에 붙여넣었다. 1시간 컷 이사 성공? 개뿔!! 결제 코드를 딴 서버에 띄우려니, 그 뱃속
User테이블 외래키(FK, Foreign Key) 조인 쿼리가 50개가 얽혀있었다! 결제 서버는 더 이상 통짜 오라클 DB에 접근을 못 하고, User 테이블 데이터가 없으니 결제 코드가 죄다 빨간 줄을 뿜으며 컴파일 에러로 뻗어버렸다. "아 씨발! 자바 코드는 예쁘게 찢어놨는데, DB 테이블을 외래키(FK)로 개더럽게 짬뽕 조인 쳐놔서 데이터베이스가 안 찢어지잖아!!" (전형적인 분산 데이터 폭망).- 아키텍트의 해결책: 물리적 외래키(Foreign Key Constraint) 완전 삭제 및 로직 레벨 조인(In-memory Join) 강제 헌법이다. 모듈러 모놀리스를 짤 때 제일 중요한 건 DB다! 아키텍트는 DBA 목을 조르고 DB 툴에서
ADD CONSTRAINT FOREIGN KEYSQL 쿼리 칠 권한을 100% 박탈(금지)시켜야 한다. User 테이블과 Pay 테이블은 서로 1도 모르는 남남이다. FK 쇠고랑을 풀고 오직user_id (String 텍스트)만 논리적으로 들고 있게 놔둬라. 데이터가 꼬이면(Referential Integrity) 어떡하냐고? 그건 551장 보상 트랜잭션(SAGA)이나 자바 코드 로직(App Level) 단에서 멱살 쥐고 맞춰야 한다. DB 엔진(오라클)의 외래키 제약 마술에 의존하는 순간(Database Coupling), 영원히 그 1통짜리 오라클 DB 감옥에서 1발자국도 찢어져 탈출할 수 없는 지옥의 족쇄에 묶이게 된다.
- 아키텍트의 해결책: 물리적 외래키(Foreign Key Constraint) 완전 삭제 및 로직 레벨 조인(In-memory Join) 강제 헌법이다. 모듈러 모놀리스를 짤 때 제일 중요한 건 DB다! 아키텍트는 DBA 목을 조르고 DB 툴에서
-
시나리오 — '이벤트 폭풍(Event Storming)'이 낳은 로컬 스레드 OOM(Out of Memory) 즉사: 모듈 간 통신을 예쁘게 비동기로 짠다고
Spring ApplicationEvent (로컬 이벤트 버스)떡칠을 했다. 주문이주문됨 ㅋ툭 던지면, 알림 봇이 받고 쿠폰 봇이 받고 배송 봇이 받았다. 블랙프라이데이 1만 명이 주문을 때렸다. 카프카(Kafka) 같은 튼튼한 큐(Queue) 댐이 없으니까, 1만 건의 이벤트 쪽지 100만 개가 톰캣(Tomcat) 서버 1대 뱃속 RAM 메모리 공간 허공에 붕 뜨며 스레드 큐(Local Buffer)에 쌓여버렸다! 톰캣 램(RAM) 16GB가 3초 만에 꽉 차버리고 시뻘건OutOfMemoryError를 뱉으며 서버 1대가 통째로 셧다운 즉사했다.- 아키텍트의 해결책: 아웃박스 패턴(Outbox Pattern 548장 연계)과 Kafka 댐 브릿지의 조기 투입이다. 1대의 램(RAM) 공간을 무한의 이벤트 대기실(Buffer)로 쓰는 건 시한폭탄이다. 아키텍트는 사내 망분리 모놀리스라 할지라도, 이벤트를 쏘는 행위만큼은 절대 톰캣 메모리에 둥둥 띄우지 않는다. "야!
주문됨이벤트 텍스트 쪼가리를 당장 내 오라클 DB 뱃속Outbox_Table에 하드디스크 INSERT 쳐서 영구 박제(Persist) 시켜놔! 그리고 뒤에서 도는 찌끄레기 봇이 그 테이블을 1초마다 읽어가서(Polling/CDC) 처리하게 만들어!" 이벤트의 생존 공간을 RAM(휘발성 휘청임)에서 Disk(영구 보존 방파제)로 찍어 누르는 이 무식한 DB 쿠션(Outbox) 땜질이 모놀리스 서버 1대의 생명줄을 1,000배로 연장하는 철벽 설계다.
- 아키텍트의 해결책: 아웃박스 패턴(Outbox Pattern 548장 연계)과 Kafka 댐 브릿지의 조기 투입이다. 1대의 램(RAM) 공간을 무한의 이벤트 대기실(Buffer)로 쓰는 건 시한폭탄이다. 아키텍트는 사내 망분리 모놀리스라 할지라도, 이벤트를 쏘는 행위만큼은 절대 톰캣 메모리에 둥둥 띄우지 않는다. "야!
도입 체크리스트
- 비즈니스적: "이 프로젝트가 사내 개발자 10명 이하짜리 스타트업, 혹은 오늘 당장 런칭해서 1달 뒤 시장 반응(A/B 테스트) 간 보고 돈 안 벌리면 쿨하게 폐기 쳐버릴 1회성 MVP(Minimum Viable Product) 도메인인가?" 그렇다면 우주가 두 쪽 나도 K8s 켜고 도커 띄우고 MSA로 50개 찢는 짓(Over-engineering)을 하면 당신은 회장님한테 고소당한다. MSA 인프라 띄우는 시간(1달)과 AWS 비용(월 1,000만 원)이 회사의 초기 시드 자본을 공중분해 시킨다. 당장 가장 빠르고 더럽게 톰캣 1대 깡통(모놀리스)으로 무지성 1초 컷 런칭을 때려서 고객의 돈(결제 100만 원)부터 1원이라도 먼저 맛보고 증명하는 속도전(Time-to-market). 그것이 모듈러 모놀리스를 0순위로 채택해야 하는 클라우드 자본주의의 절대 진리(Monolith First)다.
- 조직적: "우리 회사 깃헙(Git) 리포지토리를 여러 개로 찢을(Multi-repo) K8s 데브옵스 CI/CD 역량이 있는가, 아니면 그냥 거대 1통짜리 통짜 저장소(Mono-repo)를 강제해야 하는 구닥다리 팀인가?" 모듈러 모놀리스는 필연적으로 1개의 거대한 깃헙 1통짜리 저장소(Monorepo)에 백엔드 개발자 50명이 다 같이 달라붙어 PR(Pull Request) 충돌 지옥을 겪는 병목을 피할 수 없다. 아키텍트는 반드시 이 1통짜리 빌드 속도 10분 지연을 타파하기 위해,
Gradle Multi-project나Bazel,Nx같은 초고속 캐싱 빌드 시스템을 젠킨스(CI)에 박아, "내가 수정한 '결제' 모듈만 1초 컷으로 컴파일 쳐서 빌드 올려주는 핀셋 빌드 최적화망"을 인프라로 닦아 바쳐야 50명의 개발자가 멱살 잡지 않고 1통 속에서 평화롭게 동거할 수 있다.
안티패턴
-
"모듈만 예쁘게 패키지로 찢어놨다면서, 정작 공통 유틸(Common Util) 폴더 1개를 파놓고 전사 50개 모듈이 거기에 1만 개의
import빨대를 꽂아 다 같이 엮여버리는 '거미줄 코어(God Common)' 대재앙 🕸️": 주니어들이 제일 많이 싸는 똥이다. "아 날짜 변환하는 포맷 함수, 이거 주문에서도 쓰고 결제에서도 쓰니까 걍com.coupang.common.utils통짜 폴더 하나 만들어서 다 여기다 몰아넣고 50개 모듈에서 다 같이 재사용(DRY) 돌려 쓰자 ㅋ 개꿀!" ➡ 1년 뒤, 한 신입이 이common폴더 안에 있는 날짜 포맷 함수 1줄을 수정했다. 이 함수를 물고 빨던 전사 50개의 코어 모듈이 그 1줄의 나비효과 스노우볼에 맞아 연쇄적으로 폭발(Ripple Effect)하며 쇼핑몰 전체가 하얗게 셧다운 대참사 폭파 엔딩을 맞는다!! (의존성 블랙홀의 파국). -
"명심해라. 모듈러 모놀리스 (MSA도 똑같다) 생태계에서 맹목적인 '코드 재사용(DRY, Don't Repeat Yourself)'은 독사과다! 차라리 코드 100줄을 걍 미련하게 복사+붙여넣기(Copy-Paste) 해서 A팀 폴더에도 넣고, B팀 폴더에도 중복으로 넣어라!! (WET, Write Everything Twice). 코드가 중복되는 낭비의 고통이, 1개의 찌끄레기 공통 코드를 50명이 공유하다 1줄 수정에 전사 서버가 도미노 셧다운 되는 끔찍한 강결합(Tight Coupling)의 대재앙보다 1만 배 안전한 꼬리 자르기 생존술이다."
-
📢 섹션 요약 비유: 공통 유틸(Common) 폴더를 파는 짓은, 아파트 100세대가 각자 집에 정수기를 안 사고 **'아파트 1층 옥외 수돗가 딱 1개(Common)에 100가구가 파이프(Import 빨대) 100개를 직결로 다 꽂아놓고 돌려쓰는 미친 짓'**입니다. 누가 실수로 그 1층 옥외 수돗가에 독극물(버그 1줄)을 타면? 파이프를 공유하던 100가구 전 주민이 단체로 피를 토하며 즉사(전사 도미노 셧다운)합니다. 귀찮고 돈이 들더라도(코드 중복 낭비), 100가구 모두 무조건 자기 집 싱크대 안에 각자의 개인용 정수기(독립 유틸 코드 복붙)를 따로 설치해 두는 단절. 그것이 병균(버그)의 연쇄 전염을 원천 차단하는 궁극의 모듈 격벽 아키텍처입니다.
Ⅴ. 기대효과 및 결론
정량/정성 기대효과
| 구분 | 무지성 1통짜리(Spaghetti Monolith) 로직 강결합 떡칠 시절 | 껍데기만 1통, 속은 K8s MSA 찢기 수준의 캡슐화 락인 (TO-BE) | 개선 효과 |
|---|---|---|---|
| 정량 | 훗날 100만 트래픽 터져 MSA 이관(Migration) 칠 때 소스 뜯어고치는 데 1년 허비 | 패키지 폴더 1개만 복붙(Cut)해서 새 AWS 서버에 띄우면 1시간 컷 이사 종료 | 모놀리식 ➡ MSA로의 아키텍처 전환(Exit) 매몰 비용(Sunk Cost) 99% 증발 |
| 정량 | 초보 시절 무지성 MSA 50개 파드 찢기 도입으로 월 AWS 서버비 2,000만 원 폭발 | 일단 트래픽 없을 땐 톰캣 1대 깡통에 다 쑤셔 넣어 로컬 통신 돌림 (월 10만 원 컷) | 초기 스타트업 인프라 런칭 유지비용(TCO) 및 네트워크 딜레이(Latency) 0수렴 |
| 정성 | "아 옆팀 김 대리님이 내 DB 테이블 조인 걸어서 락 걸려 디비 터졌자나 ㅆㅂ" | "응 ArchUnit 컴파일러가 너 불법 Import 하는 거 막았음 ㅋ 빌드 컷 수고 ㅋ" | 모듈 간 침투 원천 봉쇄로 개발팀 50명의 정치적 싸움(Silo) 및 책임 소재 종식 |
미래 전망
- Spring Modulith (스프링 모듈리스) 공식 프레임워크의 대관식: 옛날엔 아키텍트가 몽둥이 들고 돌아다니며 "야 패키지 딴 거 Import 치지 마!" 훈수 두다 목이 쉬었다. 자바 스프링 진영(Spring 팀)이 빡쳐서 아예 2023년에
Spring Modulith라는 공식 흑마법 라이브러리를 우주에 발표했다. 개발자가 폼 잡을 필요도 없다. 이 프레임워크 1개만pom.xml에 박아 넣으면! 지가 알아서 패키지 간의 캡슐화 검사를 컴파일 단위로 쾅쾅 박아주고, 패키지 간 이벤트(Event) 던지는 걸 카프카(Kafka) 쓰듯이 0.1초 컷으로 로컬에 예쁘게 포장해 주고, 심지어 아키텍처 설계도(UML 다이어그램) 3D 그림까지 코드에서 자동으로 쫙 뽑아내어 PDF 문서로 바쳐주는 모놀리스 생태계의 절대 통치자로 전 세계 스프링을 씹어 먹고 있다. - Microservices의 환멸 주기(Trough of Disillusionment)와 거대한 회귀 (Monolith First): 가트너(Gartner)의 하이프 사이클의 정점이다. 프라임 비디오(Amazon Prime Video) 팀이 2023년 전 세계에 충격적인 논문을 발표했다. "야! 우리가 비디오 스트리밍 MSA(서버리스)로 50개 찢어서 쓰다가 AWS 요금 너무 처맞고 핑(Ping) 렉 지옥 터져서, 다시 옛날 모놀리식 1통짜리 서버로 싹 다 합쳤거든?! (Monolithic Repatriation). 그랬더니 서버 인프라 요금 90% 깎이고 비디오 로딩 렉 100배 빨라짐 ㅋㅋㅋㅋ MSA 좆까 ㅋㅋㅋ" 아마존(MSA의 창시자 급) 본진에서조차 무지성 찢기의 패악질을 반성하고, "강한 응집도가 필요한 코어 도메인은 다시 합쳐서 모듈러 모놀리스의 꿀을 빨자"는 극강의 아키텍처 대역류(Reverse-Migration) 회귀 현상이 메가 테크의 1티어 생존 전략으로 불타오르고 있다.
참고 표준
- Monolith First (Martin Fowler): MSA 찢기 뽕에 취해 전 세계 10만 개 스타트업이 파산의 늪으로 뛰어들자, 아키텍트의 대부 마틴 파울러가 멱살을 잡고 갈긴 뼈 때리는 아티클. "우주가 두 쪽 나도, 너희들 좆밥 트래픽 시절엔 무조건 1통짜리 튼튼한 모놀리스로 먼저 시작해라! 찢는 건 니들 서버가 100만 트래픽 맞고 대가리 깨졌을 때 해도 절대 늦지 않다!!"
- ArchUnit (Java Architecture Test): 코드 리뷰 할 때 인간의 흐리멍덩한 눈을 버리고, JUnit 테스트 코드 1줄로 "이
A패키지에 있는 자바 클래스는 우주 끝까지B패키지 클래스를import할 수 없다!" 라고 강제 기계적 락(Lock)을 쳐버려 컴파일을 박살 내는 극단적 방패 규약 툴.
모듈러 모놀리스 (Modular Monolith) 아키텍처는 소프트웨어 공학이 도달한 **'가장 더럽고 낡은 가성비의 깡통(1대의 서버) 속에, 가장 오만하고 결벽증적인 미래의 완벽한 뇌 구조(MSA 찢기 철학)를 억지로 욱여넣어 길들인 인류 최고의 모순 극복 타협술이자 위대한 생존의 은신처(Safehouse)'**다. 클라우드 시대의 화려한 환상(K8s, 카프카, 분산 롤백)은 초보자들을 불나방처럼 유혹하지만, 그 찬란한 분산(Decoupling)의 대가는 수백억의 인프라 폭탄 청구서와 네트워크 핑(Ping) 단절이라는 잔혹한 복수(Complexity Hell)로 돌아온다. 진정한 아키텍트는 겉멋(Hype)에 취해 AWS 요금을 태우지 않는다. 그는 조용히 낡은 톰캣 서버 단 1대를 켠다. 하지만 그 1통짜리 서버의 뱃속에는, 보이지 않는 티타늄 강철의 콘크리트 벽(Module)이 수십 겹으로 칼같이 그어져 있다. 1대의 램(RAM) 안에서 스레드들이 0.001초 컷으로 초광속 꿀을 빨며 돈을 1원 한 푼 안 내고 통신(Local Call)하지만, 단 한 놈도 옆방(모듈)의 내장(DB)을 훔쳐보지 못하는 극단적 금욕(Encapsulation)의 통제. 이 피 말리는 절제력의 뼈대야말로, 당장의 스타트업 자금 고갈(Burn-rate)을 막아내는 최강의 인큐베이터이자, 3년 뒤 1,000만 명의 트래픽 쓰나미가 몰려와 기어코 MSA의 바다로 이 모듈들을 찢어발겨 던져야 할 때(Extraction), 단 1시간 만에 칼로 툭 썰어 100대의 K8s 파드로 텔레포트시켜버리는 경이로운 탈출 런웨이(Exit Strategy)의 완벽한 예언 도면이다.
- 📢 섹션 요약 비유: 무지성 MSA 도입은 **'초보 사장이 식당 첫날 오픈하면서 강남에 100평짜리 매장 5개를 동시에 덜렁 임대해서(서버비 폭발) 종업원 50명 뽑아놓고 파리 날리며 한 달 만에 망하는 짓'**입니다. 모듈러 모놀리스는 똑똑한 사장의 **'푸드 트럭(1대 깡통 서버) 설계'**입니다. 지금은 돈이 없으니 작은 푸드 트럭 1대에서 장사합니다(가성비). 하지만 트럭 주방 도마 위는 **'초밥 칸, 고기 칸, 야채 칸(모듈 캡슐화)'**으로 1mm의 피도 섞이지 않게 완벽하게 스테인리스 격벽을 쳐놨습니다! 나중에 장사가 대박 나서 진짜 강남 식당 5개(MSA 파드 분산)를 차려야 할 찰나의 순간, 트럭에 쳐둔 그 도마 칸막이 채로 똑 떼어내서 각 식당으로 복붙만 쳐서 이사 가면(Extraction) 되는 치밀하고 완벽한 프랜차이즈 예비 마스터플랜입니다.
📌 관련 개념 맵 (Knowledge Graph)
| 개념 명칭 | 관계 및 시너지 설명 |
|---|---|
| 마이크로서비스 아키텍처 (MSA) | 모듈러 모놀리스가 기어코 3년 뒤에 변태(Evolution)하여 다다를 최종 진화의 도착지. 532장 MSA를 무지성으로 처음부터 바르면 터지니까, 모놀리스로 간 보며 숨 고르기를 하다가 돈 벌면 그 뼈대 그대로 썰어서 MSA 우주로 찢어 날아가는 100% 동일한 영혼의 쌍둥이다. (이전 장 532번 연계) |
| 도메인 주도 설계 (DDD) | 1통짜리 톰캣 서버 뱃속에서 '주문', '결제' 모듈 폴더를 무슨 기준으로 찢을 건데? 기획자랑 1주일 밤새워 토론해서 534장 Bounded Context(경계 묶기) 헌법으로 칼선을 명확히 긋지 않으면 결국 모듈러고 나발이고 거대한 스파게티 똥 덩어리로 부패한다. (이전 장 534번 연계) |
| 이벤트 주도 아키텍처 (EDA) | A 모듈이 B 모듈 찌를 때 new Class().call() 쌩코드 찌르기를 하면 결합도가 콘크리트가 된다! 무조건 스프링 뱃속의 허공에 ApplicationEvent (이벤트 텍스트 쪼가리) 1장 툭 던져서 비동기 쿠션을 쳐놔야 나중에 이걸 카프카(Kafka)로 1초 컷 스위칭해서 서버를 찢을 수 있다. (이전 장 538번 연계) |
| 안티패턴: 분산 모놀리스 | 모듈러 모놀리스의 완벽한 대척점이자 인류 최악의 쓰레기 구조. 모듈러 모놀리스가 "서버 1댄데, 코드는 예쁘게 찢어둠 ㅋ (극강 가성비+유지보수 천국)"이라면, 분산 모놀리스(537장)는 "서버는 50대로 찢었는데, 코드가 거미줄 똥이라 1개 뻗으면 50대 싹 다 뻗음 ㅋ (돈지랄+유지보수 지옥)" 이다. (이전 장 537번 연계) |
| 단일 장애점 (SPOF) | 모듈러 모놀리스의 어쩔 수 없는 숙명적 십자가. 어쨌든 AWS EC2 서버 1대 깡통 위에서 도니까, AWS 해당 존(AZ)에 벼락 떨어져 전원 나가면 내 모든 주문/결제 모듈이 다 같이 동반 즉사하는 치명적 1통짜리 리스크는 감내해야만 한다. (571장 융합 설계로 땜질 필요). |
👶 어린이를 위한 3줄 비유 설명
- 내가 블록 장난감을 만드는데, 처음부터 로봇 팔, 다리, 머리를 다 본드 칠해서(강결합/스파게티) 통째로 딱딱하게 한 덩어리로 만들어버리면 나중에 팔만 다른 모양으로 고칠 수가 없어서 버려야 해요 ㅠㅠ.
- 그렇다고 팔다리 머리를 다 분해해서 책상 사방에 널어두면 조종하기 너무 빡세고 정신없죠 (무지성 MSA 50개 찢기의 멸망).
- 그래서 나는 똑똑하게, 로봇을 1개의 커다란 박스(서버 1대) 안에 깔끔하게 담아두면서도! 팔, 다리, 머리는 본드로 안 붙이고 자석(모듈러 쪼개기)으로 톡톡 뗐다 붙였다 할 수 있게 짱 안전하고 예쁘게 조립해 두는 완벽한 타협 마술을 '모듈러 모놀리스'라고 부른답니다! 나중에 팔만 똑! 떼서 다른 로봇에 붙여줄 수 있어요!