분산된 MSA repo, AI 시대엔 이렇게 묶어 일합니다
들어가기
이 글의 결론은 단순해요. 당연하게 여겨지는 불합리함을 비판적 사고로 편리하게 바꿔보려는 시도 중 하나로, 분산된 저장소를 완전히 합치지 않고도 멀티 레포를 서브모듈로 관리해서 이슈 추적 흐름을 줄일 수 있었어요.
이 글에서 다루는 범위는 세 가지예요.
- 문제를 어떻게 정의했는지
- 왜 서브모듈을 선택했는지
- 오늘 바로 시작할 최소 도입 단계
1. 한 기능을 개발할 때마다 IDE 창이 늘어났어요
분산된 MSA(마이크로서비스 아키텍처) 구조에서는 한 기능을 만들 때 IDE 창이 여러 개 떠요. 서비스별 저장소(repo)가 따로 있기 때문이에요.
여기서 진짜 비용은 코드 작성 시간이 아니었어요. 맥락을 파악하는 시간이 더 컸어요.
- 어떤 저장소가 이 이슈에 연관되는지 다시 찾아요
- 각 저장소 브랜치 상태를 다시 확인해요
AI를 함께 쓰면 이 비용은 더 커져요. 에이전트에게도 컨텍스트를 여러 번 나눠서 전달해야 하기 때문에, 작업을 나누는 것부터 비효율적이에요.
2. 문제는 저장소 개수가 아니라 맥락이 자주 끊기는 구조였어요
처음에는 "저장소가 많아서 불편하다"라고만 생각했어요. 그런데 실제로는 불편의 핵심이 달랐어요.
아래 항목 중 2개 이상이면 같은 문제를 겪고 있을 가능성이 커요.
- 이슈 하나를 보는데 IDE, 브라우저, CI 탭을 계속 왕복해요
- AI에게 같은 배경 설명을 여러 번 전달해요
- 변경 범위를 매번 사람이 수동으로 추적해요
3. 제가 도입한 구조: 도메인 디렉토리 생성 + 서브모듈 연결
해결은 단순했어요. 관련 저장소를 임의의 상위 디렉토리로 묶고, Git 서브모듈(저장소를 링크로 연결해 독립 이력을 유지하는 방식)로 연결했어요.
이 글에서는 내부 식별자를 일반화해서 설명할게요.
A, B, C -> XXX(레거시)D, E, F -> {DOMAIN}(담당 도메인)
도메인 워크스페이스와 서브모듈 구조도
도입 목적은 하나였어요. 기존 독립성을 깨지 않고 탐색 동선을 줄이는 것.
4. 왜 서브모듈이었는가: 3가지 대안 비교
도입 전에 세 가지 대안을 비교했어요.
아래 용어는 이렇게 보시면 돼요.
- Git Subtree: 여러 저장소 코드를 한 저장소로 합쳐 관리하는 방식
- Git Submodule: 저장소를 링크로 연결해 독립 이력을 유지하는 방식
| 대안 | 전환 비용 | 브랜치 독립성 | CI/CD 영향 | AI 컨텍스트 탐색성 | 운영 난이도 | 판단 |
|---|---|---|---|---|---|---|
| 현상유지(분산 저장소) | 낮음 | 높음 | 없음 | 낮음 | 중간 | 탐색 비용이 계속 누적 |
| Git Subtree | 중간 | 중간 | 중간 | 중간 | 높음 | 병합/동기화 운영 부담 큼 |
| Git Submodule | 중간 | 높음 | 낮음 | 높음 | 중간 | 현 시점 최적 선택 |
핵심 기준은 두 가지였어요.
- 기존 git/CI/CD를 흔들지 않을 것
- 개별 브랜치 운영을 유지할 것
서브모듈은 이 두 조건을 모두 만족했어요.
5. 도입 후 무엇이 달라졌나
가장 큰 변화는 이슈 추적 흐름이었어요. 전에는 "위치 찾기"에 시간을 썼고, 지금은 "문제 해결"에 집중할 수 있어요.
| 구간 | 도입 전 | 도입 후 |
|---|---|---|
| 연관 서비스 찾기 | 저장소별 위치를 따로 탐색 | 워크스페이스에서 동시 확인 |
| 브랜치 상태 확인 | 서비스별 개별 확인 | 연관 모듈만 빠르게 확인 |
| AI 컨텍스트 전달 | 배경 설명을 여러 번 분할 전달 | 한 번에 맥락 전달 |
| CI/CD 검증 | 파이프라인을 넓게 확인 | 영향 서비스 중심으로 검증 |
기준 시나리오는 "연관 저장소 3개가 함께 바뀌는 이슈 1건"이에요. 이 시나리오에서 추적 구간 4개가 모두 짧아졌어요. AI 컨텍스트 전달 횟수는 "여러 번"에서 "1번"으로 줄었어요.
체감된 변화는 아래와 같아요.
- 탐색 시작까지의 준비 시간이 줄었어요
- AI와의 대화에서 반복 설명이 줄었어요
- 기존 저장소의 git/CI/CD 경로는 문제 없이 유지됐어요
- 서비스별 브랜치 전략도 그대로 유지됐어요
6. 비용과 한계도 분명했어요
좋은 점만 있었던 건 아니에요.
가장 먼저 체감한 비용은 초기 Gradle 로딩 시간 증가였어요. 워크스페이스를 처음 여는 순간은 분명 느려요.
또 하나의 비용은 운영 규율이에요. 서브모듈은 "자동으로 잘 굴러가는 구조"가 아니거든요.
비용이 생기는 시점도 비교적 명확했어요.
-
워크스페이스를 처음 여는 시점
-
릴리즈 직전에 서브모듈을 동기화하는 시점
-
포인터 업데이트 규칙이 필요해요
-
동기화 기준 브랜치를 팀이 합의해야 해요
-
온보딩 문서가 없으면 신규 인원이 쉽게 혼란을 겪어요
결국 기술 자체보다 운영 규칙이 더 중요했어요.
7. 이 방식이 특히 유리한 팀
아래 조건에 가까울수록 효과가 컸어요.
- 시스템이 아직 미성숙하고 구조가 자주 바뀌어요
- 도메인 책임은 있는데 저장소는 흩어져 있어요
- AI 보조 개발을 자주 써서 컨텍스트 전달 비용이 커요
반대로 중앙 플랫폼이 이미 강한 팀도 있어요. 또 저장소 통합이 이미 끝난 팀도 있고요. 이런 경우에는 다른 전략이 더 맞을 수 있어요.
8. 오늘 바로 시작하는 3단계
큰 전환보다 작은 실험이 안전해요. 아래 순서(1 → 2 → 3)면 첫 도입 판단이 가능해요.
1) 도메인 경계 정의
- 레거시 그룹과 도메인 그룹을 먼저 나눠요
- 한 이슈에서 함께 바뀌는 저장소를 우선 후보로 잡아요
2) 워크스페이스 생성 + 서브모듈 연결
- 상위 디렉토리를 만들고 저장소를 서브모듈로 연결해요
- IDE는 이 상위 루트를 기준으로 열면 돼요
3) 운영 룰 고정
- 언제 포인터를 올리는지 시점을 고정해요
- 코드리뷰에서 서브모듈 포인터 diff(가리키는 커밋 해시 변경)를 확인해요
- 릴리즈 전 검증 순서를 문서로 남겨요
마무리
지금 제 결론은 명확해요. 완전한 통합보다, 맥락 손실을 먼저 줄이는 게 효과적이었어요.
도메인 워크스페이스+서브모듈은 정답이 아니에요. 하지만 분산 저장소로 고통받는 팀에게는 현실적인 중간 해법이 돼요.
AI 시대에는 더 그래요. 문제 해결 속도는 모델 성능만이 아니라, 맥락을 얼마나 끊기지 않게 유지하느냐에서 크게 갈려요.
