frontEnd에서의 MSA도입 (Micro FrontEnd)

Mincho·2023년 10월 23일
1

cs지식

목록 보기
9/10
post-thumbnail

 저희 회사에서는 기존의 모놀릭한 시스템을 운영해 왔습니다. 모놀릭한 아키텍쳐를 구성은 초기에 하나의 아키텍쳐로 구성되어 있기 때문에 서비스 하나인 경우 개발, 관리, 테스트 및 배포 등이 매우 용이했습니다.

 실제로 지금까지 제가 진행해왔던 프로젝트들은 대규모 서비스를 지원하지는 않았기 때문에 하나의 서비스이자 아키텍쳐로 관리해 왔습니다. 하지만 저희 회사에서는 여러 서비스가 생김에 따라 문제가 발생했습니다.

  • 서비스의 규모가 커짐에 따라 따로 유지 보수가 매우 어려워짐.
  • 규모가 크기 때문에 서비스를 따로 나눠서 팀단위 작업이 힘들어짐.
  • 장애 발생시 하나라 묶여져 있는 여러 서비스에 영향을 줄 수 있음.

이러한 문제들은 실제로 많은 기업들에서 발생하였고 하나의 아키텍쳐로 이루어진 모놀릭한 아키텍쳐는 분산할 필요성이 대두되기 시작했습니다.


MSA 아키텍쳐

 그래서 도입된 아키텍쳐는 MSA(Micro Service Architecture)입니다. 말 그대로 하나의 서비스를 여러개의 서비스로 나누어 대규모 서비스를 좀 더 효율적으로 구성한 아키텍쳐입니다.

  • 각 마이크로서비스는 다른 마이크로서비스와 독립적으로 사용되기 때문에 기술스택에 있어서 확장성을 유지하며 개발할 수 있음.
  • 특정 마이크로서비스가 중단되더라도 다른 마이크로서비스는 중단되지 않고 정상적으로 가동가능함.
  • 독립적이기 때문에 특정 서비스를 배포하더라도 중단되지않고 서비스 이용이 가능해짐.

 실제로도 카카오, 당근 ,토스, 네이버, 야놀자, 오늘의 집, 배달의 민족 등등 대규모 서비스를 운영하고 있는 기업들은 MSA를 가지고 있습니다. 저희 또한 여러가지 서비스를 가지고 있고 이 서비스들을 각각 여러 팀들이 분담해서 맡기 때문에 MSA로의 전환이 불가피해졌습니다.

프론트엔드에서의 MSA

 이러한 MSA도입으로 인한 이점들을 프론트엔드 생태계에 도입한 것이 바로 Micro FrontEnd입니다.

대표적인 방식이 컨테이너 어플리케이션과 마이크로 어플리케이션을 분리하고 런타임에서 컨테이너 어플리케이션이 마이크로 어플리케이션들을 통합하는 것입니다. 어플리케이션들은 런타임 환경에서 통합이 되고 각자의 마이크로 서비스마다 개발 생명 주기를 가질 수 있게 됩니다. 그러면 이를 구성하는 Module Federation에 대해 알아보겠습니다.

Module Federation

 웹팩 5버전이 출시되면서 생긴 기능인 Module Federation은 동적으로 다른 빌드의 모듈 코드를 불러와 실행할 수 있게 해줍니다. 이를 위해 우리가 숙지해야 할 것들이 있습니다.

  • host와 remote : 말 그대로 host는 메인이라고 보면 됩니다. 예를 들어 우리가 어떤 어플리케이션에 접속했을 때 가지고 있는 공통된 header나 footer 혹은 menubar같은 것을 페이지 로드 시 빌드 파일로 둘 수 있습니다.
    remote는 호스트에 의해 불러지는 빌드로 예시로 menu바 클릭시 라우팅되어 보여지는 콘텐츠라고 할 수 있겠습니다.
  • 중요한 점은 빌드 된 모듈은 런타임에서 모두 양방향을 소비될 수 있다는 것입니다.

Host

chainWebpack: (config) => {
    config.optimization.delete("splitChunks");
    config
      .plugin("module-federation-plugin")
      .use(require("webpack").container.ModuleFederationPlugin, [
        {
          name: "hostApp",
          filename: "host.remoteEntry.js",
          remotes: {
                 core: 'core@http://localhost:2000/core.remoteEntry.js',
                 main: "main@http://localhost:3001/main.remoteEntry.js",
         		 products: "products@http://localhost:3002/products.remoteEntry.js",
         		 order: "order@http://localhost:3003/order.remoteEntry.js",
          },
          exposes: {
         			'./Host': './src/Host'
       	  },
          shared: {
            vue: {
              singleton: true,
            },
          },
        }

호스트는 모든 리모트 어플리케이션 모듈을 import할 수 있습니다. remotes에 있는 4개의 remote앱과 연동할 수 있도록 exposes에 Host App을 노출시킵니다.

<script setup lang="ts">
const MenuBar = () => import("core/MenuBar");
const MainPage = () => import("main/MainPage");
const ProductsPage = () => import("products/ProductPage")
</setup>

그리고 다음과 같이 디자인 시스템은 core에서 임포트하고 각 페이지 요소들을 가져옵니다.

Core

chainWebpack: (config) => {
    config.optimization.delete("splitChunks");
    config
      .plugin("module-federation-plugin")
      .use(require("webpack").container.ModuleFederationPlugin, [
        {
          name: "core",
          filename: "core.remoteEntry.js",
          exposes: {
         		 './TheHeader': './src/TheHeader'
         		 './Menubar': './src/Menubar'
       	  },
          shared: {
            vue: {
              singleton: true,
            },
          },
        }

 다음과 같이 Core모듈 컴포넌트는 공통 디자인 컴포넌트 시스템의 설계 패턴입니다. exposes를 확인하면 header, menubar등을 확인할 수 있습니다.

Remote

    chainWebpack: (config) => {
      config.optimization.delete('splitChunks');
      config
        .plugin('module-federation-plugin')
        .use(require('webpack').container.ModuleFederationPlugin, [
          {
            name: 'hostMaestro',
            filename: 'remoteEntry.js',
            remotes: {
         		shell: 'shell@http://localhost:3000/shell.remoteEntry.js',
         		core: 'core@http://localhost:2000/core.remoteEntry.js',
       		},
             exposes: {
         		"./MainApplication": "./src/MainApplication",
       		},
             shared: {
            vue: {
              singleton: true,
            },
          },
        ]);
    },

 마지막으로 Remote 애플리케이션입니다. 페이지를 host에 기반에서 노출되며 로컬에서 3000번 이상의 포트에서 호스트로 동작합니다.

 이렇게 크게 세가지 구성요소로 알아봤습니다. 이것은 단일 어플리케이션으로 통합은 런타임에서 일어납니다. 핵심은 개발팀에게는 이 것들이 독립된 어플리케이션처럼 작업을 하고, 서비스 이용자에게는 단일 어플리케이션으로써 보이게 합니다.

 완성도 있는 서비스를 갖추기 위해서는 서버 측, 네트워크 측면 등 많은 문제 해결이 필요합니다. 하지만 더 큰 도약을 위해 끊임없는 노력이 필요합니다.

Reference
https://www.kimcoder.io/blog/micro-frontend-module-federation
https://www.youtube.com/watch?v=DHPeeEvDbdo!

👍올바른 피드백은 언제든지 환영입니다~!

profile
사진찍는 개발자.

0개의 댓글