본문 바로가기
카테고리 없음

[E-commerce Project] 1주차 - Spring의 동작원리

by 갈릭 deep잉 소스좋아 2024. 4. 22.

평소에 대규모 트래픽 관련해서 현업에서는 어떻게 트래픽 처리를 하나 늘 궁금했다.

그래서 e-commerce와 관련한 프로젝트를 하기로 했다!
사실, 대규모 트래픽을 처리하는 주제는 여러 부분이 있겠지만 일상에서 가장 와닿고 떠오르기 쉬운 게 주문처리이기 때문이다. (실제로 어떤 이커머스 플랫폼에서는 블랙프라이데이를 진행하는 2주동안 트래픽이 약 300% 증가했다는 기사도 있다.)

트래픽이 저렇게 증가했는데도 어떻게 서버가 다운되지 않고 무사이 이벤트를 마칠 수 있었을까? 그게 너무 궁금했다.

궁금증을 해소하기 위해 글로 읽는 것도 좋지만 역시 나는 몸으로 익혀봐야 바로 안다!!ㅋㅋ

 

1. 기술 선정

우선 프로젝트의 뼈대를 구축할 프레임워크로는 Spring을 골랐다.

이전에는 Express랑 Nest.js로 서버개발을 해왔는데 Spring을 고른 이유는 크게 세 가지이다.

 

-  Spring은 완전히 객체지향설계를 권장하는 프레임워크이다.

 

- Spring은 Spring Security와 JPA, Spring Batch 등 개발자 친화적인 라이브러리가 상당히 잘 활성화되어있다.

(프로젝트의 기간이 짧기 때문에 라이브러리의 도움을 받는 것이 좋아 보였다)

 

- Nest.js 또한 객체지향설계 방법을 따르기 때문에 Spring의 동작원리만 익힌다면 러닝커브가 문제 될 것이라고는 생각 들지 않았다.

 

그러면 이제 스프링이 무엇이고 어떻게 동작하는지 알아보자!!!

 

Spring이란?

자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크로서 엔터프라이즈급 애플리케이션을 개발하기 위한 모든 기능을 종합적으로 제공하는 경량화된 솔루션이다.


공식문서에서의 정의는 이러한데 쉽게 말하면 자바로 개발하는 애플리케이션 서버이다.

자바로 개발하기 때문에 당연히 자바의 개발철칙인 객체지향설계를 준수하고 권장하고 있다.

 

특히, Spring에서도 Nest.js와 동일하게 IoC와 DI에 주목을 해야 하는데

 

IoC(Inversion of Control)가 뭐예요?

제어의 주체가 개발자가 아닌 프레임워크라는 뜻으로 때에 따라 프레임워크가 작성된 코드를 호출하는 기술이다.

객체의 생명주기의 관리까지 모든 객체에 대한 제어권을 프레임워크가 가진다

  • 프로그래머와 프레임워크의 주체가 바뀌었다고 표현한다.
    • 일반적인 경우라면 '개발자'가 미리 정한 순서에 따라 생성, 실행을 주도, 의도했다면(개발자가 제어권을 가졌다.)
    • IoC 가 등장한 이후는 객체의 생성, 생명주기, 관리까지 모든 객체에 대한 주도권을 프레임워크가 가진 것이다.
      (프레임워크가 관리)
  • IoC를 통해 Application을 구성하는 객체 간의 낮은 결합도를 유지할 수 있다.
  • IoC의 역할을 담당하는 것이 Spring Container이다. (Spring Container가 IoC를 담당한다.)
  • Spring ContaIner를 IoC Container라고도 한다. 

객체에 대한 모든 관리를 프로그래머가 아닌 프레임워크가 가지기에 안정성이 올라가고 유지보수가 용이하다는 장점이 있다. 추가로 스프링에는 빈이라는 객체가 있는데 

빈(Bean)은 스프링 컨테이너에 의해 관리되는 재사용 가능한 소프트웨어 컴포넌트이다.

라고 정의하고 있지만 쉽게 말해서 스프링 컨테이너에 등록된 객체라고 생각하면 된다.

이 Bean을 통해 의존성을 주입하고 인스턴스의 생성과 소멸을 관리한다.

 

스프링 Bean을 사용하는 이유???

가장 큰 이유는 스프링 간 객체가 의존관계를 관리하도록 하는 것에 가장 큰 목적이 있다. 

객체가 의존관계를 등록할 때 스프링 컨테이너에서 해당하는 Bean을 찾고, 그 Bean과 의존성을 만든다.

즉, 객체 간의 의존관계를 스프링 컨테이너가 관리하도록 함에 목적이 있다.

 

 

그럼 DI(Dependency Injection)는 뭔가요?

의존성 객체를 개발자가 생성하지 않고 클래스를 Bean으로 등록해 놓으면 Bean으로 등록된 객체를 프레임워크가 찾아서 알아서 주입해 주는 기술이다. 이를 통해 모듈 간의 결합도를 낮출 수 있다.

  •  IoC 가 행하여질 때, Spring 내부의 객체들 간의 관계를 관리할 때 의존성을 주입한다.
  • Application 실행 시점에 객체 간의 관계를 결정, 주입해준다.
  • 결합도를 낮추고 유연성을 확보한다.
  • 스프링에서는 생성자 주입 방식을 권장한다.

DI를 통해 모듈 간의 결합도를 낮추는 게 가장 큰 장점인데 이것이 왜 장점이 되느냐?

소프트웨어가 발전하면 수많은 기능이 추가되고 기능이 추가됨에 따라 코드를 수정하는 일이 빈번해질 수 있다.

그러나 의존성 주입을 통해 각 클래스가 독립된 기능만을 수행하게 하고 모듈의 결합도를 낮추어 이러면 무언가 하나의 기능을 추가해도 하나의 클래스에만 추가를 하거나 수정하면 되기 때문에 유지보수가 용이하다.

 

또한 스프링 컨테이너는 기본적으로 싱글톤 패턴을 사용하는데, 싱글톤 패턴이란 객체를 1개만 생성하여, 필요한 곳에서 공유하는 방법이다. 기본적으로 객체를 생성할 때 사용하는 new키워드랑은 다르다. 스프링 컨테이너 내부에서 객체(Bean)를 생성하고 관리하기 때문에 new키워드를 사용해서 객체를 생성할 때보다 메모리 관리 측면에서 용이하다.

 

 

Spring 동작원리

 

DispatcherServlet

애플리케이션으로 들어오는 모든 Request를 받는 부분. Request를 실제로 처리할 Controller에게 전달하고 그 결괏값을 받아서 View에 전달하여 적절한 응답을 생성할 수 있도록 흐름을 제어한다.

 

HandlerMapping

Request URL에 따라 각각 어떤 Controller가 실제로 처리할 것인지 찾아주는 역할을 한다.

 

Controller

Request를 직접 처리한 후 그 결과를 다시 DispatcherServelt에 돌려준다.

 

ModelAndView

Controller가 처리한 결과와 그 결과를 보여줄 View에 관한 정보를 담고 있는 객체이다.

 

ViewResolver

View 관련 정보를 갖고 클라이언트에게 포워딩할 실제 View 파일을 찾아주는 역할을 한다.

 

View

Controller가 처리한 결과값을 보여줄 View를 생성한다.

 

 

댓글