MPA에서 SPA로

taypark·2020년 8월 31일
3

서론

본론

결론

참고자료


서론

2019 NHN Forward Seoul에서 발표한 '레거시 웹 서비스 길들이기: 서버 개발자의 SPA 적용기'를 보고 현존하는 많은 레거시 웹 서비스들을 보다 효율적인 SPA로 전환했을 때 발생하는 이점이나 문제점 등 이슈들을 알아보고 차후 프로젝트에 적용하기 위해 작성하는 글입니다. 이를 참고하여 레거시 시스템과 모던 시스템의 차이를 파악하여 문제점과 이슈들을 개선하는 방법을 알아봅니다.

결론부터 말하자면 레거시 시스템은 자바 스프링 부트를 이용한 것이고, 차후에 Vue.js와 백엔드를 이용하여 FE와 BE를 분리합니다.


본론

웹 패러다임은 급격하게 변화해왔습니다. AJAX의 도입과 Javascript의 급격한 부상으로 높은 성능을 기대할 수 있는 웹 애플리케이션이 속속히 등장하고 있습니다. 또한 개발의 편리성을 주는 툴들이 많이 나오고 있습니다.

하지만 여전히 레거시 시스템들은 존재합니다. 느린 로딩속도와 버튼을 클릭할 때마다 모든 것을 새로고침해야하는 불편함 때문에 리소스적 낭비도 심했고 이로 인해 다중 접속자가 발생했다면 서버는 렌더링만 하다가 뻗어버릴 것입니다.

레거시 웹 아키텍처모놀리식(Monolithic)이라는 개념을 사용하는데, 이는 모든 로직이 하나의 애플리케이션에 포함되어있다는 말입니다.

하지만 현대 애플리케이션은 진화하였습니다. 필요한 부분만 변화를 주고, 리소스를 적게 사용하여 가볍고 빠른 웹을 사용할 수 있고, 이를 통해 많은 동접자가 있더라도 더 나은 리소스 관리로 서버의 부담을 줄입니다. 요즘은 이를 자바스크립트로 구현합니다. 또한 RESTful API웹 프레임워크의 발달등의 기술의 고도화로 View보다는 Data에 집중하게 되었습니다.

하지만 여기서 레거시를 어떻게 나눌것인지 고민을 하게 합니다. 보통 우리는 웹 서비스를 생각할 때 디자인패턴 중 하나인 MVC 패턴을 떠올립니다.

MVC 패턴과 MPA, SPA

여기 간단한 시나리오가 있습니다.

  1. 브라우저가 웹 페이지를 접속하여 데이터를 요청한다.
  2. 컨트롤러가 요청을 받아들여 모델, 즉 DB나 API를 통해 데이터를 받아 가공한다.
  3. 이를 정적 파일로 작성하여 브라우저가 파싱할 수 있는 형태로 바꾼다.
  4. 이를 에 전달한다.

MPA, MultiPage Application, 즉 레거시 시스템의 경우 JSPFreemarker로 html을 작성하였습니다.(이것을 서버에서 작업했기 때문에 서버 렌더링이라고 합니다.) 단 비동기적 요청을 처리하지 못해 다수의 페이지(멀티 페이지)를 구성해야했고, 서비스의 크기가 커지고 웹 UI가 복잡해지면서 화면 구성에 필요한 데이터를 표현하는것도 복잡해집니다. 만약 거기에 데이터간 dependency가 존재하고 다수의 API 호출이 필요하다면 더 복잡한 로직이 됩니다. 즉, 이를 처리하기위해 서버렌더링이 많아지고 서버 과부하가 발생합니다.

모던 웹 개발인 SPA는 웹 페이지 구현에 필요한 모든 정적 리소스를 최초 한 번 다운로드하고 이후 필요한 데이터는 비동기(AJAX)로 받아 화면을 구성합니다. 그렇다면 하나의 페이지만 존재하고 페이지 전환 및 구성을 자바스크립트로 구현하게됩니다.

이로 인한 장점입니다.

  • HTML JS CSS 등 정적 리소스를 한 번만 로드하기에 HTTP request 감소, 성능 개선
  • 화면구성에 필요한 데이터(JSON)만 API로 받아오면 되므로 불필요한 네트워크 통신 감소

하지만 단점도 존재합니다.

  • 검색엔진 최적화(SEO, Search Engine Optimization)에 어려움

검색엔진 최적화는 웹페이지 검색엔진이 자료를 수집하고 순위를 매기는 방식에 맞게 웹 페이지를 구성해서 검색 결과의 상위에 나올 수 있게 하는 작업을 말합니다. 자세한 것은 검색엔진 최적화 위키백과를 참고해주세요.

이런 이유로 SPA는 이런 곳에 적합합니다.

  • 로그인이 필수인 곳(SEO가 불필요)
  • 페이지 내 동적 요소가 많은 시스템(참고로, 현존하는 웹 서비스들은 대부분 동적요소로 작용합니다.)
  • UI구성이 복잡하고 데이터가 많이 필요한 웹페이지

만약 비즈니스 로직에서 이같은 상황이 발생했다면 과감하게 프론트와 백엔드를 분리하는 작업을 권장드립니다.


웹 프론트엔드 프레임워크 고르기

모던 웹 개발은 통짜 코딩을 하지 않습니다. 웹 개발에 편리한 툴들이 존재하고 이것들을 묶어놓은 것이 웹 프레임워크라 합니다. 이 중 프론트엔드에 대해서는 3대장이 존재합니다.

  • Angular: '모든 기능'을 가집니다만, 기능이 너무 많아 배우는데 오래 걸립니다.
  • React: 강력한 기능을 가집니다. 더 필요한 도구는 개발자가 필요에 따라 선택할 수 있으므로 개발자의 선호도가 높습니다.
  • Vue: 최소 기능으로 빠른 개발을 할 수 있습니다. 만약 자바 개발자라면, 자바 스프링 부트와 연동하는 라이브러리도 존재합니다.

이 셋 중에서 조직에 적합한 프레임워크를 고르면 됩니다. 하지만 이 세 프레임워크 모두 ES6기반의 문법으로 동작하므로, 최신 자바스크립트 문법에 대해 알아둘 필요가 있습니다.

let, const
arrow Function
import, export
class
require
template literal
spread operator

정도는 아셔야 지장이 없습니다.

만약 더 좋은 기능이나 새로운 기능을 사용하고 싶으시면 알맞는 프레임워크를 사용하면 되나, 검증된 프레임워크를 사용하기를 권장드립니다. 그러기 위한 여러가지 체크리스트가 있습니다.

  • 사용자가 적절히 있는가
  • 프레임워크 생태계가 괜찮은가
  • 릴리즈 한 후 시간이 좀 됐는가(안정성이 검증되었는가)
  • 충분한 레퍼런스가 있는가
  • 문서화가 잘 되어있는가

정도입니다.


웹팩의 도입

이전 글 에서 웹팩을 다루었습니다. 다시 설명하자면 웹팩의 도입으로 HTTP 요청을 줄여 효율적인 웹 요청을 위해 기능이나 모듈별로 번들링하는것을 말합니다. 이는 숙련된 웹팩 사용자에게는 문제가 되지 않지만, 초심자에게는 적절한 가이드라인이 없어 다른 레퍼런스들을 많이 참조하는것을 권장합니다.


프로젝트 구성 중 모든 요청을 WAS에서 해결했던 레거시 시스템

기본적으로 웹 서버의 구조는 다음과 같습니다.

  • Browser <-> Web Server <-> Web Application Server <-> DB

이 구조에 대해서는 웹서버 vs 웹 어플리케이션 서버를 참고하였습니다. 이 구조에 대해 잘 모르시겠다면 참고해주세요.

우리가 사용하는 웹서비스는 정적 페이지동적 페이지가 있습니다.

정적 페이지는 항상 같은 컨텐츠를 가지는 웹 페이지를 의미하고 정적 페이지는 주어진 값에 따라 다른 결과를 반환하는 웹 페이지를 의미합니다.

일반적으로 웹 서버는 정적 컨텐츠를 저장한 컴퓨터에서 브라우저에게 바로 제공할 수 있습니다. 그러나 동적 페이지의 경우 DB조회 등이 필요한 것은 웹 어플리케이션 서버, 즉 WAS에게 넘겨 이를 수행하도록 합니다. WAS는 웹 서버로부터 요청받은 내용을 DB에거 제공받은 후 이를 다시 웹서버로, 웹서버는 브라우저에게 제공합니다.

두 서버가 하나만 존재할 수도 있고, 공존할 수도 있습니다. 공존을 하는 이유는 로드 밸런싱Fail over보안을 위함입니다.

다시 돌아가서, 레거시 시스템에서의 문제는 정적 리소스들도 모두 WAS에서 처리했었습니다(웹서버를 공존하여 사용하였기 때문에 비효율적). 하지만 SPA로 바꾼다고 해도 이를 그대로 유지하면 별 차이가 없어보입니다. 그래서 발표자분께서 말씀하신 내용으로는 다음과 같습니다.

  • HTTP요청과 static resource는 웹 서버(nginx)에서 응답
  • AJAX API는 bypass로 WAS에서 JSON으로 응답

이렇게되면 정적 데이터는 빠르게 웹 서버에서 가져오고, 동적 데이터는 WAS를 통해 DB를 조회하여 과부하를 줄일 수 있습니다.


API 호출방식의 변화

레거시 시스템에서는 서버 렌더링을 위해 API 명세에 맞는 모든 자바 객체들을 구현해야 합니다. 그렇다면 많은 연산을 서버가 수행하게 되는데, 이는 과부하의 원인이 되기도 했습니다. 이를 개선하기 위해 API명세에 맞추지 않고 게이트웨이를 통해 모든 API 엔드포인트를 통합하는 컴포넌트를 세우려는 계획을 합니다.

API 게이트웨이를 만들어 프록시 서버처럼 사용합니다. API 엔드포인트를 통합하여 API 라우팅 기능을 제공합니다. 그렇다면 불필요한 데이터 객체들을 구현하지 않고 간단한 JSON 형식으로 바로 제공하여 서버 렌더링을 줄이게 되었습니다.


FE 상태관리 전략

레거시 시스템에서 컴포넌트간 데이터 의존성을 이벤트리스너 등으로 처리했습니다. 이는 데이터 플로우와 로직의 복잡성을 가중화시킵니다.

이를 해결하기 위해 웹 프레임워크에서 제공하는 상태관리 라이브러리를 사용합니다. Vue.js의 경우 Vuex, React는 Redux가 있습니다. 이는 데이터를 중앙 집중적으로 관리하고 데이터 의존성을 가진 컴포넌트들이 이 데이터를 바라보게하여, 데이터의 변화에 맞춰 컴포넌트를 변화시킵니다. 그렇게되면 컴포넌트간 의존성을 해소하고 로직의 복잡도를 효과적으로 줄일 수 있습니다.


배포 환경에 따른 설정값 처리

배포 환경이 모두 다릅니다. Git flow 전략처럼 배포, 개발, 베타 등 다른 배포환경이 존재합니다.

결론만 말하자면 개발 환경은 개발 편의성을 위해, 운영 환경은 성능 위주로 설정을 구성하는 것입니다.


결과?

이로 인한 결과를 정리합니다.

  • 성능

    1. SPA로의 전환으로 인한 API 호출 수 감소
    2. 웹팩의 도입으로 웹 리소스 최적화
    3. 모듈간 의존성 파악이 쉽고 성능 최적화에 도움
  • 운영

    빌드/배포를 격리하여 필요한 모듈만 빌드/배포함

  • 개발

    • 프론트엔드: 웹 프레임워크 도입, 개발 일관성을 위해 ESLint등 툴을 사용하고 재사용가능 컴포넌트 개발을 지향
    • 백엔드: 서버 렌더링이 급격히 적어졌으니 데이터에 집중할 수 있음. API 게이트웨이 역할 및 인증 기능에 충실할 수 있음

결론

MPA에서 SPA에서 전환하면서 결정한 사항들과 이점, 장단점들을 나열하며 정리했습니다. 이를 통해 우리는 필요한 부분에서 적절한 아키텍처의 사용과 자바스크립트 라이브러리(혹은 프레임워크) 사용으로 효율적인 웹 애플리케이션 서비스를 구성할 수 있습니다.

참고자료

https://www.youtube.com/watch?v=E-HTpT7LibY&feature=youtu.be

https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html

https://ko.wikipedia.org/wiki/%EA%B2%80%EC%83%89_%EC%97%94%EC%A7%84_%EC%B5%9C%EC%A0%81%ED%99%94

https://ijbgo.tistory.com/9

profile
인생은 하드코어하게

0개의 댓글