Skip to main content

Chapter 5. 운영, 성능, 장애 대응

Module Federation 기반 프론트엔드 아키텍처에서 운영의 핵심은 독립 배포런타임 호환성 유지다. 배포 속도를 높이는 것만으로는 충분하지 않으며, host와 remote 사이의 계약(contract), 캐시 반영 시점, 장애 복구 방식, 보안 통제가 함께 설계되어야 한다.

5.1 배포 전략

remote 독립 배포

remote는 host와 별도로 배포할 수 있어야 한다. 이것이 Module Federation의 주요 장점이다. 다만 독립 배포아무 제약 없는 배포를 뜻하지 않는다. remote가 독립적으로 배포되려면 host가 기대하는 공개 인터페이스를 안정적으로 유지해야 한다.

여기서 공개 인터페이스는 다음을 포함한다.

  • expose된 모듈 경로
  • 컴포넌트의 props 구조
  • export 이름과 타입
  • 이벤트, 상태 계약, 공유 라이브러리 버전 정책

실무에서는 remote를 하나의 “런타임 라이브러리”처럼 다루는 것이 안전하다. 내부 구현은 자유롭게 바꿀 수 있지만, 외부에 노출된 계약은 신중하게 관리해야 한다.

host와 remote 배포 순서

배포 순서는 변경 종류에 따라 달라진다. 항상 host 먼저 또는 항상 remote 먼저로 고정하면 오히려 장애 가능성이 커진다.

변경 유형권장 순서이유
remote 내부 구현만 변경, 공개 계약 유지remote → 필요 시 hosthost가 기존 계약대로 계속 동작 가능
host가 새로운 remote API/모듈을 사용remote → hosthost가 먼저 배포되면 아직 없는 API를 호출할 수 있음
remote의 기존 API 제거 또는 변경host를 먼저 호환 상태로 배포 → 이후 remote 정리breaking change 방지
shared dependency의 major 변경카나리 배포 → 단계적 확산런타임 충돌 가능성이 큼

정리하면, 새 기능 추가는 remote 먼저, 기존 계약 제거는 host 호환 배포가 먼저가 기본 원칙이다.

backward compatibility 유지

운영 안정성을 위해서는 가능한 한 추가적(additive) 변경을 우선해야 한다.

권장 방식은 다음과 같다.

  • 기존 expose 경로를 갑자기 바꾸지 않는다.
  • props 변경은 optional 필드 추가 방식으로 진행한다.
  • 기존 export를 바로 제거하지 않고 deprecated 상태를 거친다.
  • 기본값을 제공해 host가 이전 호출 방식으로도 동작하게 한다.
  • breaking change가 필요하면 일정 기간 old/new 계약을 함께 지원한다.

즉, remote는 새 버전이 배포된 직후에도 이전 host와 일정 기간 함께 동작할 수 있어야 한다.

롤백 전략

롤백은 단순히 “이전 코드 다시 배포”로 끝나지 않는다. 브라우저 캐시, CDN 캐시, 이미 열린 탭의 상태까지 고려해야 한다.

안전한 롤백을 위해서는 다음이 필요하다.

  • 불변 아티팩트(immutable artifact) 운영
  • 버전별 배포 경로 유지
  • 이전 버전으로 빠르게 되돌릴 수 있는 포인터 구조
  • host와 remote 각각의 독립 롤백 경로 확보

가장 안정적인 방식은 다음 패턴이다.

  • 실제 파일은 버전 경로 또는 해시 파일명으로 배포
  • host는 고정 URL 대신 manifest를 조회해 현재 remote 위치를 확인
  • 문제 발생 시 manifest가 가리키는 버전만 이전 것으로 되돌림

이 방식은 재배포 없이도 빠른 롤백이 가능하고, 캐시 오염도 줄일 수 있다.


5.2 성능 최적화 포인트

초기 로딩 비용

Module Federation은 런타임에 remote를 가져오기 때문에 초기 로딩 비용이 증가할 수 있다. 특히 첫 진입 시 remoteEntry 조회, 공유 라이브러리 초기화, 실제 청크 다운로드가 연쇄적으로 발생할 수 있다.

따라서 remote는 다음 원칙으로 로드하는 것이 좋다.

  • route 단위 lazy loading
  • 사용자 액션 직전에 prefetch/presolve
  • 초기 화면에 반드시 필요하지 않은 remote는 지연 로드
  • 로딩 중에는 skeleton 또는 placeholder 제공

핵심은 “모든 remote를 앱 시작 시점에 미리 불러오지 않는 것”이다.

remoteEntry 크기 관리

remoteEntry.js는 remote를 찾고 초기화하는 진입점이다. 이 파일이 커지면 전체 로딩 체감 성능이 악화된다.

관리 포인트는 다음과 같다.

  • expose 수를 과도하게 늘리지 않는다.
  • remoteEntry에 실제 앱 로직이 섞이지 않도록 한다.
  • 큰 의존성은 별도 청크로 분리한다.
  • 공개 대상이 아닌 내부 모듈은 expose하지 않는다.

remoteEntry는 가능한 한 작고 안정적인 인덱스 파일처럼 유지하는 것이 좋다.

shared dependency 최적화

공유 의존성은 중복 번들을 줄이는 데 유용하지만, 무분별하게 공유하면 오히려 초기화 복잡도와 버전 충돌이 커질 수 있다.

일반적으로 다음 의존성이 공유 대상에 적합하다.

  • React, React DOM 같은 큰 런타임
  • 디자인 시스템 코어 패키지
  • 조직 전체에서 버전 정책을 맞출 수 있는 공통 라이브러리

반대로 자주 바뀌거나 작은 유틸리티까지 모두 shared로 묶는 것은 비효율적일 수 있다. 크고 안정적이며 조직 차원에서 버전 정렬이 가능한 패키지 중심으로 공유하는 것이 안전하다.

중복 번들 방지

host와 여러 remote가 같은 라이브러리를 각각 번들링하면 다운로드 크기와 메모리 사용량이 커진다. 중복 번들을 줄이려면 다음이 필요하다.

  • 주요 라이브러리의 버전 정렬
  • 번들 분석 도구를 통한 중복 확인
  • 공유 대상 라이브러리의 명확한 기준 수립
  • 디자인 시스템, 상태관리, 라우터 등의 중복 포함 여부 주기적 점검

단, “모든 것을 공유”가 정답은 아니다. 공유 비용보다 중복 비용이 큰 라이브러리만 선별적으로 공유해야 한다.


5.3 캐시 전략

파일명 해시

정적 청크 파일은 content hash 기반 파일명을 사용하는 것이 기본이다. 파일 내용이 바뀌지 않으면 URL도 바뀌지 않고, 내용이 바뀌면 URL이 달라지므로 장기 캐시에 적합하다.

예를 들어 다음과 같은 전략이 일반적이다.

  • 애플리케이션 청크: 해시 파일명 + 장기 캐시
  • manifest: 짧은 TTL 또는 재검증
  • unversioned remoteEntry: 짧은 TTL 또는 no-cache

CDN 캐시

CDN 캐시는 성능에 매우 중요하지만, remote 반영 지연의 주요 원인이기도 하다.

권장 정책은 분리 운영이다.

  • 해시가 붙은 청크 파일: immutable 중심의 장기 캐시
  • manifest 또는 버전 포인터 파일: 짧은 TTL, 빠른 재검증
  • 고정 경로 remoteEntry: 장기 캐시 금지

가장 좋은 구조는 manifest는 짧게 캐시하고, 실제 아티팩트는 길게 캐시하는 방식이다.

cache invalidation

캐시 무효화는 “파일을 덮어쓰기만 하면 해결된다”는 수준으로 접근하면 안 된다. 브라우저, CDN, 프록시, 서비스워커가 각각 다른 시점에 캐시를 유지할 수 있기 때문이다.

안전한 방법은 다음 순서다.

  1. 새 버전 파일을 새로운 URL로 배포
  2. manifest 또는 버전 포인터 갱신
  3. 필요 시 CDN purge 수행
  4. 기존 세션은 점진적으로 새 버전으로 전환

즉, 동일 URL 덮어쓰기보다 새 URL 발급 방식이 훨씬 안전하다.

remote 버전 반영 시점

remote를 배포했다고 해서 모든 사용자가 즉시 새 버전을 보게 되는 것은 아니다.

버전 반영 시점은 다음 요소에 따라 달라진다.

  • 브라우저 캐시 유지 시간
  • CDN TTL
  • manifest 재조회 시점
  • 사용자가 페이지를 새로고침했는지 여부
  • 이미 열린 탭에서 해당 remote가 로드되었는지 여부

실무적으로는 다음처럼 이해하는 것이 맞다.

  • 새로 열린 세션은 비교적 빨리 새 버전을 볼 수 있다.
  • 이미 열린 탭은 새로고침 전까지 이전 버전을 계속 사용할 수 있다.
  • 따라서 “배포 즉시 전체 반영”을 전제로 설계하면 안 된다.

5.4 장애 대응

remote 로드 실패 처리

remote 로드 실패는 생각보다 흔하다. 원인은 다양하다.

  • 네트워크 장애
  • CDN 응답 오류
  • 잘못된 배포 경로
  • CORS/CSP 문제
  • remoteEntry 로드 성공 후 init/get 단계 실패
  • shared dependency 버전 충돌

따라서 host는 remote 로드를 “성공이 보장된 동작”이 아니라 실패 가능한 외부 의존성 호출로 다뤄야 한다.

권장 처리 방식은 다음과 같다.

  • 로드 단계별 오류를 구분해 기록
  • 사용자에게 전체 앱 오류가 아닌 기능 단위 오류로 노출
  • 오류 메시지에 remote 이름, 버전, URL, 단계 정보를 포함
  • host 전체 크래시로 전파되지 않도록 경계 처리

graceful fallback

원격 모듈 장애가 전체 서비스 장애로 이어지면 안 된다. 각 remote는 독립 기능 단위로 실패를 격리해야 한다.

대표적인 fallback 방식은 다음과 같다.

  • 해당 영역만 숨기고 나머지 화면은 정상 유지
  • host가 가진 기본 UI로 대체
  • 읽기 전용 모드로 축소
  • “잠시 후 다시 시도” UI 제공
  • 특정 기능만 feature flag로 즉시 차단

핵심은 remote 실패 시 host가 최소 기능을 유지하는 것이다.

timeout/retry 정책

remote 로딩을 무한정 기다리게 두면 사용자 경험이 급격히 나빠진다. 따라서 명시적인 timeout과 제한된 retry 정책이 필요하다.

일반적인 원칙은 다음과 같다.

  • 첫 로딩에 명시적 timeout 적용
  • 재시도는 1~2회 정도로 제한
  • exponential backoff 적용
  • 영구 오류와 일시 오류를 구분
  • 최종 실패 시 fallback UI로 전환

예를 들어 “3~5초 내 응답 없으면 실패 처리, 이후 1~2회 재시도” 정도가 현실적이다. 무한 재시도는 네트워크와 사용자 모두에게 좋지 않다.

관측성(log, metrics, tracing)

운영 환경에서는 “실패했다”보다 어디서, 얼마나, 어떤 버전에서 실패했는지를 알아야 한다.

log

로그에는 최소한 다음 정보가 포함되어야 한다.

  • host 버전
  • remote 이름과 버전
  • remote URL
  • 로드 단계(script load, init, get, mount)
  • 에러 메시지와 스택
  • 현재 라우트, 사용자 세션 식별자, trace ID

metrics

정량 지표로는 다음이 유용하다.

  • remote 로드 성공률
  • remote 로드 시간
  • timeout 발생 비율
  • retry 발생 횟수
  • fallback 렌더링 비율
  • 버전 불일치 발생 횟수

tracing

분산 추적이 가능하면 host에서 시작된 사용자 요청이 어떤 remote에서 지연되거나 실패했는지 추적하기 쉬워진다. release/version 태그를 trace에 함께 남기면 배포 직후 장애 탐지 속도가 크게 올라간다.


5.5 보안 고려사항

외부 remote 신뢰성

외부 remote는 단순한 정적 자원이 아니라 실행되는 코드다. 한 번 로드되면 host와 같은 브라우저 권한으로 동작할 수 있으므로, 신뢰할 수 없는 제3자 remote를 직접 연결하는 것은 매우 위험하다.

원칙은 명확하다.

  • 가능하면 같은 조직이 관리하는 remote만 허용
  • 배포 파이프라인과 권한을 통제
  • 외부 조직 코드를 직접 federation으로 주입하지 않음
  • 신뢰가 낮은 통합은 iframe 같은 격리 수단을 우선 고려

즉, federation은 코드 공유이지 샌드박스가 아니다.

스크립트 로딩 출처 관리

remote 스크립트는 반드시 통제된 출처에서만 로드해야 한다.

권장 사항은 다음과 같다.

  • 허용된 도메인 allowlist 운영
  • HTTPS만 허용
  • 사용자 입력으로 remote URL이 결정되지 않도록 제한
  • manifest 파일도 신뢰된 경로에서만 제공
  • 배포 이력과 아티팩트 출처를 추적 가능하게 유지

remote URL이 설정 파일이나 런타임 설정에서 바뀔 수 있다면, 그 설정 자체도 보안 통제 대상이다.

CSP 영향

동적 스크립트 로딩은 CSP(Content Security Policy)의 영향을 크게 받는다. CSP를 엄격하게 운영하는 경우 다음 항목을 점검해야 한다.

  • script-src에 remote CDN/도메인이 포함되는지
  • remote가 추가 리소스를 불러오면 connect-src, img-src, style-src, font-src가 충분한지
  • 개발용 eval 기반 설정이 프로덕션에 남아 있지 않은지
  • nonce/hash 기반 정책과 동적 remote 로딩이 충돌하지 않는지

특히 프로덕션에서 unsafe-eval 의존이 생기지 않도록 빌드 설정을 관리해야 한다.

공급망 리스크

Module Federation 환경에서는 npm 패키지, 빌드 서버, CDN, 배포 권한이 모두 공격면이 된다. 한 remote가 오염되면 host 전체에 영향을 줄 수 있다.

따라서 다음 통제가 필요하다.

  • lockfile 고정
  • dependency 취약점 스캔
  • CI/CD 접근 권한 최소화
  • 아티팩트 무결성 검증 체계
  • 배포 승인 및 변경 이력 관리
  • 주요 라이브러리와 remote의 버전 추적

공급망 보안은 애플리케이션 코드 보안과 별도로 다뤄야 하며, 특히 shared dependency와 remote 배포 권한을 엄격히 통제해야 한다.


실무 권장안

운영 관점에서 가장 안정적인 패턴은 다음과 같다. 🚦

  1. manifest 기반 remote 조회
  2. 실제 청크는 해시 파일명 + 장기 캐시
  3. manifest는 짧은 TTL
  4. remote 계약은 additive 변경 우선
  5. remote 실패 시 host fallback 보장
  6. host/remote 버전 정보를 로그·메트릭·트레이스에 공통 기록
  7. 외부 remote는 최소화하고, 출처와 권한을 강하게 통제

한 줄 정리

Module Federation 운영의 핵심은 “독립 배포” 자체가 아니라, 독립 배포를 가능하게 하는 호환성·캐시·복구·보안 체계를 함께 갖추는 것이다.

원하면 다음 단계로 이어서 문체를 더 공식 문서형으로 다듬은 버전이나 사내 가이드 스타일의 체크리스트 버전으로 재작성해주겠다.


배포 장애 대응

  1. Module Federation에서 깨지는 지점 ❌ 문제 1. host / remote 버전 불일치 Blue → Green 전환 순간 사용자 A (기존 탭) → host (old) + remote (new) 조합 발생 가능

또는

사용자 B (새 요청) → host (new) + remote (old 캐시)

👉 서로 다른 세대 조합이 섞임

문제 2. 브라우저 캐시 remoteEntry / chunk 캐시로 인해 Green 배포 완료 → 사용자 브라우저는 여전히 Blue remote 사용

👉 Blue-Green과 무관하게 발생

문제 3. long-lived session (SPA 특성) 이미 열린 탭은 host도 안 바뀌고 remote도 새로 안 가져옴

👉 “부분적으로만 업데이트된 상태” 지속

실제로 발생하는 대표 장애 component props mismatch export 이름 변경 → runtime error shared dependency 충돌 (React 두 개) lazy load 실패 (404 / init 실패)

안전하게 쓰는 방법

  1. backward compatibility 필수 remote는 항상: old host + new remote new host + old remote

👉 둘 다 동작해야 함

  1. manifest 기반 버전 고정 (강력 추천) host → 특정 remote 버전만 바라보게 고정 Blue 환경 → v1 Green 환경 → v2

👉 환경 단위로 version lock

  1. remoteEntry 캐시 전략 절대 long cache 금지 Cache-Control: no-cache

👉 항상 최신 버전 확인

  1. contract 기반 배포 규칙 breaking change는 반드시:
  2. host 먼저 대응
  3. 이후 remote 변경
  4. 장애 대비 fallback remote 실패 시: 빈 화면 ❌ fallback UI ✅ feature disable ✅