후라이
[Spring MVC] 웹 시스템 | 서블릿 | HTML | HTTP API 본문
1. 웹
https://gaeran.tistory.com/category/HTTP
HTTP 카테고리에서 HTTP의 자세한 공부 내용을 다루고 있습니다!
웹 기본 내용은 해당 게시글에서 참고하면 좋을 거 같아요:)
스프링 MVC를 들어가기에 앞서, 웹 서버(Web Server)를 리마인드 해봅니다.
1.1) 웹 서버(Web Server)
- HTTP 기반으로 동작한다.
- 정적 리소스를 제공하거나 기타 부가기능을 제공한다.
- 정적(파일) HTML, CSS, JS, 이미지, 영상 등
- 웹 서버 예시로는 NGINX 혹은 APACHE가 될 수 있겠죠
간단합니다. 클라이언트가 HTTP 메시지로 요청을 보내면, 웹 서버는 그에 응당하는 HTTP 응답을 보내면 됩니다.
그럼, 웹 애플리케이션 서버는 뭔가요?
1.2) 웹 애플리케이션 서버(WAS - Web Application Server)
- HTTP 기반으로 동작한다.
- 웹 서버 기능을 넘어 애플리케이션 로직을 처리하는 기능까지 포함한다.
- 동적 HTML 혹은 HTTP API(JSON)
- 서블릿, JSP, 스프링 MVC - 웹 애플리케이션 서버 예시로는 Tomcat, Jetty, Undertow가 있습니다.
의미가 피부로 잘 와닿지 않을 수 있는데요, 조금 더 자세히 설명해보자면
웹 서버는 기본적으로 클라이언트로부터 HTTP 요청을 받아 정적인 콘텐츠를 제공합니다.
WAS는 사용자의 HTTP 요청에 따라 "동적인 처리"가 가능합니다.
예를 들어, 사용자가 로그인 폼을 제출했을 때
서버가 데이터베이스와 통신하여 인증 정보를 확인하고 결과를 반환하는 과정이 될 수 있습니다.
동적 HTML 혹은 HTTP API는 뒤에서 자세히 설명하겠습니다만,
- WAS가 클라이언트의 요청에 따른 비즈니스 로직을 처리한 결과를 기반으로 동적으로 HTML을 생성해서 반환한다는 것입니다.
ex) 상품 목록 페이지에서 데이터베이스에서 상품 정보를 가져와 HTML로 만들어서 반환하는 경우입니다.
- HTTP API는 단순히 HTML만 반환하는 것 외에도 클라이언트와 JSON 형식의 데이터를 주고 받을 수 있습니다.
1.3) 웹 시스템 구성
사실 WAS와 DB만으로 시스템 구성이 가능합니다.
WAS는 정적 리소스와 애플리케이션 로직 모두를 제공하기 때문이죠.
그런데, 그런 경우엔 WAS가 너무 많은 역할을 담당하게 됩니다.
정적 리소스 제공으로 본질적인 비즈니스 로직 수행이 어려워질 수도 있습니다.
그래서 웹 시스템 구성 자체를 Web Server, WAS, DB로 구성합니다.
정적 리소스는 웹 서버가 처리하도록 하고, 애플리케이션 로직은 WAS에 위임합니다.
사실 웹 서버는 정적 리소스만 제공하는 역할을 하기에 잘 죽지 않습니다.
하지만, 애플리케이션 로직이 동작하는 WAS 경우에는 서버가 잘 죽을 수 있습니다.
그런 경우, Web Server가 오류 화면을 제공하게 됩니다.
2. 서블릿
HTML Form 데이터를 전송하는 예시를 들어봅니다.
<form action="/save" method="post">
<input type="text" name="username" />
<input type="text" name="age" />
... 이런식의 폼을 전송했다고 합시다.
그럼 HTTP 메시지는
이렇게 생성되어 서버측에 요청이 넘어갈 것입니다.
사실 여기서 웹 애플리케이션 서버가 할 일은 비즈니스 로직 실행이며, 데이터베이스에 save하는 요청을 처리하면 됩니다.
만약 우리가 웹 어플리케이션을 태초마을부터 하나하나 설계하면,
클라이언트로부터 받은 위 메시지를 다 까보는 작업부터 시작해서 TCP/IP 연결 등 복잡하고 많은 일련의 과정들을 해결해야 합니다. 우린 이 짓거리를 안하려고 서블릿을 사용합니다.
2.1) 서블릿은?
- Java를 기반으로 한 웹 애플리케이션의 요청/응답 처리 담당자입니다.
- JSP가 자주 언급될텐데요, 서블릿은 JSP와 달리 순수 Java 코드로 작성됩니다. (추후에 설명)
전체 시스템 구성을 살펴봅시다.
웹 브라우저가 localhost 서버를 사용한다는 가정하에, 클라이언트에게 HTTP 요청이 들어오면
WAS는 Request, Response 객체를 새로 만들어 서블릿 객체를 호출합니다.
- 개발자는 Request 객체에서 HTTP 요청 정보를 꺼내서 사용하기만 하면 됩니다.
- 그리고 Response 객체에 HTTP 응답 정보를 편하게 입력하기만 하면 됩니다.
2.2) 서블릿 컨테이너
서블릿 컨테이너는 쉽게 말해 서블릿이 실행될 수 있는 "환경"을 제공합니다.
- 서블릿 객체를 생성하고 초기화하고 호출, 종료까지를 관리합니다.
- 각각의 객체는 싱글톤으로 관리하게 됩니다.
- 톰캣과 같은 서블릿 컨테이너는 동시요청을 위한 멀티 스레드 처리를 지원합니다.
싱글톤에 대해 간단히 설명하면,
HTTP request 자체는 고객마다 요청이 다르기 때문에 요청이 들어올 때마다 새로운 request 객체를 생성하는 것이 맞습니다.
서블릿은 애초에 모든 사용자 요청에서 공통적으로 사용될 수 있는 코드(비즈니스 로직)를 포함합니다.
ex) 데이터베이스 조회, 회원 정보 읽기 등등..
이러한 객체를 매번 생성하고 소멸시키는 작업은 큰 오버헤드를 발생시키므로 새로 만들 필요는 없습니다.
단, 공유 변수 사용에는 주의해야 합니다.
2.3) 동시 요청 <멀티 스레드>
클라이언트에게 요청1이 오면 WAS는 서블릿을 호출하고, 해당 요청에 맞게 응답1을 넘겨주면 됩니다.
그런데, 누가 서블릿을 호출하나요? -> thread가 호출합니다.
전공 수업시간에 스레드 개념을 배웠을텐데요, 애플리케이션 코드를 하나하나 순차적으로 실행하는 것이 스레드가 되겠습니다.
스레드는 한번에 하나의 코드 라인을 수행하기 때문에 동시 처리를 해야하는 경우엔, 스레드를 추가로 생성하게 되겠죠.
단일 요청에는 하나의 스레드 사용에 문제가 없겠습니다만, 다중 요청시에는 문제가 생깁니다.
모종의 이유로 서블릿 문제가 생겨 요청1에 대한 처리가 지연되고 있다고 합시다.
그러던 중에 새로운 요청2가 들어오면 결론적으로 요청1과 요청2 모두 망합니다.
망하지 않으려면 요청마다 스레드를 생성하면 됩니다.
그럼 요청2에 대한 응답2가 오가고, 지연이 해결되면 요청1도 해결이 될 것입니다.
하지만, 요청마다 스레드를 생성한다는 것엔, 단점이 있습니다.
- 스레드는 생성 비용이 비싸다.
- 스레드는 컨텍스트 스위칭 비용이 발생한다.
그래서 이와 같은 단점을 보완한 "스레드 풀"을 사용합니다.
내부에 풀장처럼 스레드들이 놀고 있다가 요청이 들어오면 풀에 있는 스레드를 갖다 쓰고,
처리가 끝나면 다시 풀장에 반납하는 시스템입니다.
이렇게 처리하면,
- 스레드는 이미 생성되어 이으므로, 스레드를 생성하고 종료하는 비용이 절약되고 응답시간이 빠릅니다.
- 생성 가능한 스레드의 최대치가 있기 때문에, 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있습니다.
그리고 다시 말하자면. 위와 같은 멀티 스레드를 WAS가 처리합니다.
그래서, 개발자는 멀티 스레드 관련 코드를 신경쓰지 않아도 됩니다 :0
3. 정적 리소스 | HTML Page | HTTP API
3.1) 정적 리소스
- "고정된" HTML 파일, CSS, JS, 이미지, 영상 등의 리소스를 의미합니다.
- 웹 브라우저에게 이미 생성된 정적 리소스 파일을 요청에 따라 반환하면 됩니다.
3.2) HTML 페이지
- 위에서 말한 고정된 HTML 파일이 아니라, 동적으로 필요한 HTML 파일을 생성해서 전달합니다.
(요청한 사용자나 상황에 맞게 HTML 페이지의 내용이 달라진다는 것)
>> 데이터베이스와의 상호작용, 특정 로직 처리 결과 등 - 웹 브라우저는 반환 받은 HTML을 읽고 해석하여 화면에 표시합니다.
3.3) HTTP API
- HTML이 아닌 데이터를 전달합니다. (주로 JSON인데 XML, Plain Text등도..)
- HTTP 프로토콜을 통해 서버와 클라이언트가 데이터를 주고 받음
일반적으로 브라우저는 서버에서 받은 데이터가 HTML일 것으로 가정합니다.
그런데 서버가 HTML이 아닌 형식의 데이터를 웹 브라우저한테 보내면 웹 브라우저 입장에서는 그냥 텍스트로 출력만 합니다.
{
"product_id": 123,
"name": "Wireless Earbuds",
"price": 49.99,
"stock": true
}
HTML은 데이터와 뷰를 결합한 형태라서 브라우저에 바로 렌더링 되겠지만,
JSON은 순수 데이터만 전달하기 때문에 브라우저 입장에서는 이 데이터를 어떻게 렌더링는 건지 모르기 때문입니다.
그래서, 다양한 UI 클라이언트와 접점하게 됩니다.
웹 브라우저뿐만 아니라 모바일 앱, 데스크톱 앱, 다른 서버 등 다양한 클라이언트에서 활용 가능합니다.
'Spring' 카테고리의 다른 글
[Spring MVC] MVC 프레임워크 <2> (1) | 2024.12.19 |
---|---|
[Spring MVC] MVC 프레임워크 <1> (1) | 2024.12.19 |
객체지향에서의 다형성, 그리고 OCP (2) | 2024.12.07 |
[Spring Boot] - 스프링 입문 (6) (1) | 2024.02.13 |
[Spring Boot] - H2 데이터베이스 연결 / Database not found (0) | 2024.02.12 |