[스프링 MVC] 그래서 웹 서버가 대체 뭔데?

Junho Bae·2021년 3월 21일
7

SPRING MVC

목록 보기
1/1

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

인프런 김영한 님의 스프링 MVC 1편 - 웹 개발 핵심 기술 을 수강하고 정리한 내용입니다. 김영한님 체고.

스프링은 공부해도 공부해도 정말정말 공부할게 너무 많다. 근데 마침 김영한 님께서 MVC 강의를 다시 내주셨다니! 복습할 겸 다시 들어보려고 한다.

김영한님 강의 답게 빌드업이 조지게 좋은 만큼 서블릿부터 다시한번 해보신다고 하니까 다시 해봐야겠다.

섹션 1에서는 그냥 전반적인 클라이언트 서버 구조, 간단한 네트워크, 간단한 http 등을 슥 보고 간다. 재밌당.

웹 서버, 웹 어플리케이션 서버

웹은 기반으로 http 기반으로 통신을 합니다.
클라이언트에서 서버로 요청을 할 때, 서버에서 클라이언트로 응답할 때, http 기반으로 이루어집니다.

지금은 http의 시대!

웹 서버

  1. http 요청 : 이거 주세요!
  2. http 응답 : 여기 있어요.
  3. 정적 리소스 제공(html, css, js, 이미지, 영상) , 기타 부가기능

WAS - Web Application Server

  1. HTTP 기반으로 동작
  2. 웹 서버의 기능을 포함 +
  3. 프로그램 코드를 실행해서 어플리케이션 로직을 수행할 수가 있음! cf) 웹서버는 정적 리소스를 쓰기 때문에 사용자에게 다른 화면을 보여준다거나 하지 않음.
  4. 동적 HTML, HTTP API(REST API)
  5. 서블릿, JSP, 스프링 MVC
  6. Tomcat 등등

웹서버와의 차이?

  • 웹 서버는 정적 리소스 파일 / WAS는 애플리케이션 로직
  • 사실 둘의 용어 경계가 모호함. 서로가 서로의 기능을 포함할 수 있음.
    자바는 서블릿 컨테이너 기능을 제공하면 WAS (서블릿 없이 자바 코드를 실행하는 프레임워크도 있음)
    결론 : WAS는 애플리케이션 코드를 실행하는데 더 특화

웹 시스템 구성 - WAS,DB

-WAS, DB만으로 시스템 구성이 가능함.
-WAS는 정적 리소스, 애플리케이션 로직 모두 제공 가능.
-WAS가 너무 많은 일을 담당하는데..? 앱 로직도 실행하고, 정적 컨텐츠도 계속 제공하고…. 정작 중요한 어플리케이션 로직, 그러니까 “비싼” 로직이 이미지 이런 정적 리소스 때문에 수행이 어려워지면 안되잖아…
만약 WAS가 죽는다면? 우리가 로직을 잘못 짠다거나, 디비가 오류가 난다거나… 한다면 심지어 오류 화면 조차 노출 불가능함.

그래서, 일반적으로는

client -> web server(정적 리소스를 여기서 처리) -> WAS에서 로직 처리 -> 디비

이런 식으로 처리를 함. 시스템 리소스를 효율적으로 처리할 수가 있음. 만약 앱 리소스가 더 많이 처리한다? 그러면 WAS만 늘리면 됨.

또한, 정적 리소스 서버 그러니까 웹 서버는 잘 죽지도 않습니다. 그래서 WAS가 죽더라도, 정적 리소스 서버에서 오류화면을 띄울 수가 있습니다. + 요새는 CDN을 따로 둬서 정적 리소스 서버를 늘리기도?

만약 api만 제공한다면 was만 구축하기도 합니다.

서블릿

만약 폼 인증을 직접 구현한다면?

일단 폼 인증을 한다면 http 메시지가 생성이 되어서 날아가겠죠?

그러면

  • tcp/ip 연결 해서 소켓 여는것 부터 해서..
  • http 요청 메시지를 파싱하고..
  • 그 메시지의 메서드, url 확인하고..
  • 컨텐트 타입 확인하고..
  • http 메시지 바디 내용 파싱하고..
  • 저장 프로세스 실행하고..
  • 비즈니스 로직 실행하고 : 디비에 회원 저장.
  • http 응답 메시지 생성하고…
  • tcp/ip 응답 전달하고, 소켓 종료하고..

거기다가 만약 udp라면..? 끔찍하네요…

사실 중요한건 비즈니스 로직을 실행하는겁니다! 즉, 서블릿이 비즈니스 로직을 제외한 모든 기능들을 WAS에서 다 지원해줍니다.

서블릿 특징


@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServelt {

	@Override void service(HttpServletRequest request, HttpServletResponse respnse) {
			//애플리케이션 로직
		}
}

-어노테이션 안의 url로 들어왔을 때 처리!
-service 안의 로직만 구현하면 됨.
-request, response를 직접 파싱하고 정리하고 만들려면 이게 굉장히 귀찮겠죠? 그냥 request, response 객체를 가져다 쓰면 됩니다! request.getUsername()이런 것 처럼
-응답 정보도 response에다가 내가 원하는거 그냥 잘 넣으면 됩니다!
하지만 http 스펙은 기본적으로 알고 있어야 합니다!

서블릿

http 요청시
-was는 request, response 객체를 새로 만들어서 서블릿 객체 호출
-개발자는 request 객체에서 http 요청 정보를 편리하게 꺼내서 사용!
-개발자는 response 객체에 http 응답 정보를 편리하게 입력!
-was는 response 객체에 담겨있는 내용으로 http 응답 정보를 생성! 그러면 웹서버가 html 이쁘게 렌더링 해서 보내줍니다.

서블릿 컨테이너

서블릿을 지원하는 was 안에는 서블릿 컨테이너가 있는데, 이 서블릿 컨테이너에서 서블릿을 관리해줍니다.

  • 호출
  • 생명주기 관리
  • 톰캣처럼 서블릿을 지원하는 was를 서블릿 컨테이너라고 함.
  • 서블릿 객체는 싱글톤으로 관리 (객체를 하나만 만들어놓고 공유해서 쓰는 것)
    - 물론, request & response는 요청마다 데이터가 당연히 다르니까 항상 새로 생성되어야 하죠.
    - 하지만, HelloServelet이 필요할까요? 로직은 그냥 그대로 가져다 쓰면 되니까 굳이 계속해서 만들 필요가 없습니다.
    - 최초의 시점에 하나를 그냥 만들어 둡니다.
    - 따라서, 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근합니다.
    - 따라서, 공유변수 사용에 주의해야 합니다!!!!!
    - 서블릿 컨테이너 종료시 함꼐 종료됩니다.
  • 참고로, jsp도 서블릿으로 변환되어서 사용됩니다.
  • 동시 요청을 위한 멀티 쓰레드 역시 지원됩니다!

동시 요청 - 멀티 쓰레드

그래 알겠어. 요청이 올때마다 was의 서블릿 컨테이너에서 서블릿을 꺼내서 쓰는구나.
근데 서블릿은 누가 호출하지..? 바로 쓰레드가 호출합니다.

쓰레드

-애플리케이션 코드를 하나하나 순차적으로 실행하는 것은 쓰레드!
-자바의 메인 메서드를 실행하면 main이라는 이름의 쓰레드가 실행됩니다.
-만약 동시 처리가 필요하다면 쓰레드를 생성해야 합니다!

요청 마다 WAS가 쓰레드를 생성

장점
-동시 요청을 처리할 수 있음
-리소스가 허용할 때 까지 처리 가능
-하나의 쓰레드가 지연되어도 나머지는 정상작동

단점

  • 쓰레드는 생성 비용이 매우 비싸다! -> 고객의 요청이 올 때마다 스레드를 생성하면 응답 속도가 늦어진다.

  • 쓰레드는 컨텍스트 스위칭 비용이 발생한다! 운영체제에서 컨텍스트 스위칭..하는데…운체 강의 들어야 되는데… 과제도 해야되는데… 큰일..났네요..

  • 쓰레드 생성에 제한이 없다. like 치킨 디도스 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ : 고객 요청이 너무 많으면 만개의 쓰레드를 만들면 cpu 메모리 임계점을 넘어버려서 서버가 죽어버릴 수도 ㅋㅋㅋㅋㅋ

=> 그래서 어떻게 하냐? 대부분의 was에서는 쓰레드 풀을 만들어 놓습니다. 가령, 쓰레드 풀을 200개 만들어 놓고 있으면, 하나씩 쓰는 겁니다.

=> 그러고 쓰레드를 다 쓰면 죽이는게 아니라, 이걸 다시 반납을 해줍니다.

=> 만약 쓰레드 풀의 갯수를 넘는다면, 우리 다 찼어 못해줘! 하고 뱉어버리거나, like 맛집 대기열처럼 대기열을 받아줌. 저희는 10명까지만 받을게요!

쓰레드 풀

  • 필요한 쓰레드를 쓰레드 풀에 보관하고 관리

  • 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리. 톰캣은 최대 200개 기본 설정.

  • 요청이 오면 이미 만들어진 쓰레드를 풀에서 꺼내서 사용한다.

  • 끝나면 반납한다.

  • 다 쓰고 있으면 거절하거나 대기하도록 설정한다.

장점

  • 쓰레드가 미리 생성되어 있으므로, 쓰레드를 생성하고 종료하는 비용이 절약되고 응답시간이 빠르다.
  • 생성 가능한 쓰레드의 최대치가 있으므로, 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다. 물론 너무 많으면 쓰레드를 늘려야겠죠?

실무 팁

  • was의 주요 튜닝 포인트는 최대 쓰레드 수(max thread)이다. 요 값을 튜닝했을 때 가장 효과가 좋습니다.

  • 이 값이 너무 낮으면? 우리 서버는 사양이 낮아..그러니까 그냥 안전하게 하자… 근데 서비스가 대박이 나서 막 요청이 100개가 들어와.
    -> 그러면 10개만 돌고 90개는 기다리겠지? 그럼 막 으악 고객 요청 겁나 많이 들어와 어떻게?
    -> 개발자니까 이제 가서 cpu 사용량을 봅니다. 음..5% 사용중이군…ㅋㅋ아주 치욕적이네요..못해도 50%는 써야되는데!!!! 근데 이걸로 막 aws 인스턴스 10개로 늘리고…. 돈 10배로 나가고…

  • 그럼 높게 가자. 한 만개 쓰자.
    -> cpu, 메모리 리소스 임계점 초과
    -> 서버 다운 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

장애 발생시?
-장애가 났으면 일단 처리해야지. 급하니까. 클라우드면 늘리고 나중에 튜닝합시다.
-아니면 평소에 튜닝 잘하세요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

적정 숫자는 어떻게 찾나요?
-그냥 100개 쓰세요 200개 쓰세요 하는건 잘못된 겁니다! 어플리케이션 로직의 복잡도, cpu 메모리, io 리소스 상황에 따라 모두 다릅니다!
-성능 테스트를 결국 해봐야 합니다.
: 최대한 실제 서비스와 유사하게 성능 테스트 시도, nGrinder 추천. 스크립트 짜서 쭉 요청 해보기! 만약 못받으면 병목 포인트 찾아서 튜닝!

핵심

-WAS가 멀티 쓰레드를 해줍니다. 이거 직접 짜면 머리 터져요.
-개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않으면 됩니다. 비즈니스 로직만 처리하면 됩니다! 설정만 해주면 댑니다!
-개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발, WAS의 가아아아아자아아앙앙 큰 장점
-멀티 쓰레드 환경이기 때문에 싱글톤 객체(서블릿, 스프링 빈)은 주의해서 사용할 것!

HTML, HTTP API, CSR, SSR

HTTP API

  • 단순 html이 아닌, 데이터를 전달 :
  • 주로 json 형식 사용
  • 다양한 시스템에서 호출.
    ex) 앱 개발자랑 일을 하면, 앱에는 다 컴포넌트로 UI가 구현되어 있음. 데이터만 주세요! 혹은 ajax 통신에서 js로 요청이 온다! 그러면 이제 주면 됩니당. 혹은 서버끼리 통신을 하는데 html을 줄 필요는 없잖아요?

요새는 다들 리엑트, vue 같은것들 쓰니까 api 넘겨주면 되는 것 같습니당. 또 micro service 후.. 에서 많이 쓰죠.

백엔드에서 고민할 것은 세가지! 정적 리소스 어떻게 제공할거야, 동적 Html 어떻게 제공할거야, api 어떻게 줄거야?

서버사이드 렌더링, 클라이언트 사이드 렌더링

  1. SSR - 서버 사이드 렌더링
  • 서버에서 최종 html을 동적으로 생성해서 클라이언트에 전달!
  • 서버가 html을 싹 그려서 그대로 전달. 웹 브라우저는 단순하게 보여주기만 하면 됨.
  • jsp, 타임리프 (백엔드 개발자)
  1. 클라이언트 사이드 렌더링
  • 사실 나도 처음 웹 하면서 헷갈렸던 부분 ㅋㅋㅋㅋㅋㅋ 리엑트 쓰는 팀원한테 그럼 렌더링은 어케하는거야? 했다가 비웃음 당함..
  • html 결과를 자바스크립트를 사용해 웹 브라우저에서 동적으로 생성해서 적용!
  • 막 돔 해가지고 컴포넌트 막 만들어서 바뀌게.
  • 주로 동적인 화면에 사용. 웹 한경을 마치 앱 처럼 필요한 부분부분 변경할 수 있음!
  • react, vue.js (프론트 개발자)

사실 세상이 막 딱딱 나눠지진 않죠. 서로 동시에 지원하는 프레임 워크도 있고 막 그렇습니다.

그럼 백엔드가 어디까지 해야해요?

  1. 백엔드 - 서버 사이드 렌더링 기술
    -jsp(거의 안씁니다), 타임리프.
    -화면이 정적이고 복잡하지 않을 때 서용
    -백엔드 개발자는 서버 사이드 렌더링 기술 학습해야합니다! 타임리프 솔직히 이거 한 며칠이면 바로 현업 들어갈 수 있어요.
  2. 웹 프론트엔드 - 클라이언트 사이드 렌더링 기술
  • 리엑트, 뷰
  • 복잡하고 동적인 UI 사용
  • 웹 프론트엔드 개발자의 전문분야
  1. 선택과 집중
    -백엔드 개발자의 웹 프론드엔드 기술 학습은 옵션
    -백엔드는 서버, db, 인프라 등등드읃으드으 너무 많아요
    -웹 프론트엔드도 깊이있게 잘하려면 숙련에 오랜 시간이 필요합니다.
    -풀스택..? 환상입니다. 다 못합니다. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 배민 개발팀장님이 풀스택인 사람을 거의 못봤다 하면 없는거지 뭐..
    -백엔드가 적성에 맞으면, 이 분야를 잘 하면서 프론트 기술을 공부해두는게 좋다.
    -요즘 주니어는 잘 하기도…하더라….

나는 아무래도 막 클라이언트 프론트 쪽 보다는 백이 좋더라… 예전 프로젝트에서 급하게 프론트 하던 일이 있었는데.. ~다 때려 부수고 싶더라...~

그래도 요새는 리엑트 공부해보고 싶다!

자바 웹 기술 역사

고대에 서블릿이란게 있었습니다.
1. 서블릿
고대에 서블릿이 있었는데 자바 코드로 html을 만들기가 어려웠죠. 그래서 jsp가 나옵니다.
2. jsp : html은 편리하기는 한데 비즈니스 로직이 너무 많아서 막 한 파일에 와장창
3. 서블릿, jsp 조합 mvc 패턴 사용 : 관심사를 나누는 거죠.
4. mvc 프레임워크 춘추 전국 시대 : 2000 ~ 2010년 초. 아 이거 비슷하니까 나도 프레임워크 만들어봐야징. 스트럿츠, 앱워크 , 등등. mvc 패턴 자동화, 웹 기술 편리하게 사용하는 등의 다양한 기능 지원.
5. 애노테이션 기반의 스프링 mvc 등장! : @Controller. 얘는 모든 장단점을 다 해결해버렸어요. 원래 스프링 + 다른 MVC 프레임워크 이렇게 썼었는데. 안그래도 스프링 코어는 많이 썼었는데 MVC를 준다? 바로 뚝딱. 거기다가 애노테이션으로 깔끔. 그냥 통일.
6. 스프링 부트의 등장

  • 결국 개발자들이 불편해 했던 것들을 다 자동화해줌.
  • 스프링 부트는 서버를 내장!
  • 과거에는 was(톰캣 등)를 서버에다 설치하고 실행. 그리고 소스코드는 소스코드대로 따로 만들어서 빌드. jar 모아서 war로. 그리고 이걸 배포 폴더에다가 넣어가지고 막 아주 그냥 소스 빌드하고 아주 복잡하고 번거로웠는데
  • 스프링 부트가 그냥 빌드할 때 톰캣 서버를 넣어버림. 이러면 서버에 톰캣, was를 할 필요가 없음. 걍 jar를 실행해 버리면 그냥 한방에 실행.

최신기술 - 스프링 웹 기술의 분화 : Web Servlet - Spring MVC, Web Reactive - Spring WebFlux

WebFlux?
특징

  • 완전한 비동기 넌 블록킹 처리
  • 최소 쓰레드로 최대 성능 - 쓰레드 컨텍스트 스위칭 비용 효율화
    : cpu 코어가 4개다? 그러면 쓰레드를 4개 (+1)로 맞춤. 그래서 컨텍스트 스위칭 비율이 매우 효율적임.
  • 함수형 스타일로 개발 - 동시 처리 코드 효율화.
    : 동시에 상품도 조회하고, 주문 서버도 조회하고, 막 api를 동시에 여러개 찔러서 조합해. 이걸로 자바 코드를 짜면 번거롭고 쉽지 않음. 이걸 함수형 스타일로 짜면 효율적임
  • 서블릿 기술을 사용하지 않음. netty 디폴트 사용.
  • 그러니까 자바도 nodejs 스타일로 개발을 할 수 있는겨

그런데

  • 웹 플럭스는 기술적 난이도가 매우 높음
  • 아직은 RDB 지원이 부족함. RDB 쓰면 사실상 쓰기 어렵다고 봐야됨. Redis, Elastic Search, MongoDB 등에서는 쓸 수 있음
  • 일반 MVC의 쓰레드 모델도 충분히 빠르다..
  • 성능이 굉장히 중요하고 아키텍처가 매우 복잡하다.. 그럴 때 사용
  • 실무에서 아직 많이 사용하지는 않음. 공부할 것도 많고.. 난이도도 높고… MVC도 충분히 빠르고..
  • 국내 100개 프로젝트 중 1개도 안될 정도로 비중이 적을 겁니다.

요번에 프로젝트가 MSA로 진행하면서 Web Flux를 쓸까 할 때 RDB 쓰지 말라 했던게
그래서구낭..

자바 뷰 템플릿 역사

  • jsp
  • 프리마커
  • 타임리프 : 이거 쓰세용.
profile
SKKU Humanities & Computer Science

0개의 댓글