🎈 Web Application
웹서버라는것은 HTTP 프로토콜을 기반으로 소통하고 , 데이터를 주고받을 수 있습니다. 대부분의 현태의 데이터 전송이 가능하고, 서버 간의 데이터를 주고받을 때도 대부분 HTTP를 사용합니다.
웹 서버(Web Server)는 클라이언트로부터 HTTP 요청을 받아들이고, HTTP 프로토콜을 기반으로 웹 페이지와 다른 리소스를 제공하는 소프트웨어입니다. 웹 서버는 웹 브라우저와 같은 클라이언트가 요청하는 정적인(HTML, CSS, 이미지 등) 웹 페이지를 처리하고 전송하는 역할을 담당합니다.
일반적으로 웹 서버는 HTTP 요청을 받아들이는 기능과 요청에 대한 적절한 응답을 제공하는 기능을 갖추고 있습니다. 웹 서버는 클라이언트와의 통신을 위해 HTTP 프로토콜을 사용하며, HTTP 요청에 대한 처리 결과를 HTTP 응답으로 반환합니다.
웹 애플리케이션 서버(Web Application Server, WAS)는 동적인 웹 애플리케이션을 실행하고 관리하는 미들웨어 소프트웨어입니다. WAS는 웹 서버의 역할뿐만 아니라 애플리케이션 실행 환경과 데이터베이스와의 통신 등을 담당하여 웹 애플리케이션을 실행하는 데 필요한 여러 기능을 제공합니다.
프로그램 코드를 실행해서 애플리케이션 로직을 수행하기 때문에 동적 HTML 및 HTTP API(REST API)등이 WAS를 통해 제공이 됩니다. (ex. 아파치 톰캣)
- 애플리케이션 실행 환경 제공: WAS는 자체적으로 자바 애플리케이션의 실행 환경을 갖추고 있으며, 웹 애플리케이션의 실행과 관리를 담당합니다. 웹 애플리케이션을 실행하기 위해 자바 서블릿과 JSP(JavaServer Pages)와 같은 컴포넌트를 지원합니다.
- 스레드 관리 및 트랜잭션 처리: WAS는 여러 클라이언트의 요청을 동시에 처리하기 위해 스레드 풀을 사용하여 스레드를 관리합니다. 또한, 트랜잭션 처리와 같은 다중 작업을 원활하게 수행하도록 지원합니다.
- 데이터베이스와의 연동: 웹 애플리케이션은 데이터베이스와의 상호작용이 필요한 경우가 많습니다. WAS는 데이터베이스와의 통신을 지원하여 데이터의 조회, 저장, 갱신 등을 처리할 수 있도록 합니다.
- 세션 관리: 웹 애플리케이션은 세션 관리를 통해 사용자의 로그인 상태와 상호작용을 유지합니다. WAS는 세션 관리 기능을 제공하여 사용자의 세션 상태를 효율적으로 관리합니다.
- 클러스터링: 대규모 웹 애플리케이션에서는 여러 WAS 인스턴스를 클러스터로 구성하여 부하 분산과 고가용성을 제공할 수 있습니다.
웹 시스템은 WAS - DB만으로도 간단하게 시스템 구성이 가능합니다. WAS는 정적 리소스와 애플리케이션 로직 모두 제공이 가능하기 때문입니다. 하지만, 1개의 WAS를 가지고만 운영을 하게되면
역할이 커지게 되며 서버 과부하의 우려가 있으며, 중요도가 낮은 정적 리소스 때문에 중요한 애플리케이션 로직의 수행이 어려울 수 있습니다.
정적 리소스만 제공하는 웹 서버는 다운이 잘 안되지만 애플리케이션 로직이 동작하는 WAS 서버는 잘 다운됩니다.
WAS나 DB에서 장애가 발생했을 시 WEB 서버가 오류 화면을 제공해줄 수 있습니다.
📋 서버에서 처리해야 하는 업무
웹 애플리케이션 서버를 직접 구현 시 웹 브라우저가 생성한 요청 HTTP 메세지를 분석합니다. 요청 메세지가 어떠한 형태로 보내졌는지 확인 후 비즈니스 로직 실행을 통해 데이터 베이스에 저장을 요청합니다. 이 후 HTTP 응답 메세지를 시작라인 생성, Header 생성, 메세지 바디에 HTML을 생성한 응답메세지를 만든 후 TCP/IP에 응답메세지를 전달한 후 소켓을 종료합니다.
이러한 많은 과정들을 축약하기 위해 서블릿의 개념이 등장하였습니다. 서블릿을 지원하는 WAS를 사용함으로서 HTTP 요청 메세지를 읽는 과정부터 응답 메세지의 생성까지 전부 진행해줍니다.
@WebServlet(name="helloServlet", urlPatterns = "/hello")
-> urlPatterns(/hello)의 URL이 호출되면 서블릿 코드가 실행됩니다.
public class HelloServlet extends HttpServlet { -> httpServlet을 상속받습니다.
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet.service");
//애플리케이션 로직을 작성합니다.
}
**HTTP 요청 정보를 편리하게 사용 할 수 있는 HttpServletRequest
**HTTP 응답 정보를 편리하게 사용할 수 있는 HttpServletResponse 들을 객체 생성하여 편리하게 사용이 가능합니다.
HTTP 요청이 오면 WAS 는 Request, Response 객체를 새로 만들어서 서블릿 객체를 호출해주어 개발자는 Request 객체에서는 HTTP 요청 정보를 편리하게 꺼내서 사용, Response 객체에 담겨있는 HTTP 응답 정보를 편리하게 입력할 수 있게 됩니다. WAS는 Response 객체에 담겨있는 내용을 바탕으로 HTTP 응답 메세지를 생성 후 전달합니다.
서블릿 컨테이너
서블릿 컨테이너(Servlet Container)는 웹 애플리케이션 서버(또는 웹 컨테이너)의 일부로서, 서블릿의 생명주기를 관리하고 서블릿을 실행하는 환경을 제공하는 소프트웨어입니다. 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 합니다. 서블릿 컨테이너는 클라이언트의 요청에 대해 적절한 서블릿을 생성, 호출,관리하고 서블릿이 요청을 처리한 결과를 클라이언트에게 반환합니다.
서블릿 객체는 싱글톤으로 관리 (객체 한개 생성 후 객체 공유) 클라이언트의 요청이 올 때마다 객체를 생성하는것은 비효율 적이기 때문에 , 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재사용이 가능하도록 하는 것이 좋습니다. 모든 클라이언트의 요청은 동일한 서블릿 객체 인스턴스에 접근할 수 있으며, 서블릿 컨테이너가 종료 될 때 함께 종료됩니다. (💥 공유 (멤버변수) 변수를 사용할 때 굉장히 주의가 필요)
동시 요청 - 멀티 쓰레드✍️💡
클라이언트가 요청을 하면 WAS에 요청이 전달되면 TCP/IP 커넥션으로 연결이 되며 서블릿을 호출하게되며 응답을 줄 수 있습니다. 여기서 서블릿 객체를 호출하는 당사자가 굉장히 중요합니다. 바로 쓰레드가 서블릿을 호출하게 됩니다.
쓰레드란 ?
쓰레드(Thread)는 프로세스 내에서 실행되는 실행 단위로, 프로세스의 자원을 공유하면서 동시에 여러 작업을 처리할 수 있도록 해주는 기본적인 실행 단위입니다. 애플리케이션 코드를 하나 하나 순차적으로 실행해주며, 자바 메인 메서드를 처음 실행하면 main 이라는 이름의 쓰레드가 실행되는 것 입니다.
일반적으로 하나의 프로세스는 하나의 메인 쓰레드를 가지고 있고, 이 메인 쓰레드에서 프로그램의 주요 로직이 실행됩니다. 쓰레드가 없다면 자바 애플리케이션 실행이 불가능하며, 쓰레드는 한번에 하나의 코드라인만 수행합니다. 그러나 프로그램이 다중 작업을 동시에 처리해야 할 경우가 있습니다. 이때 추가적인 쓰레드를 생성하여 각 작업을 병렬적으로 처리할 수 있습니다.
📋 쓰레드의 단일 요청
단일 쓰레드 모델에서는 프로그램의 모든 작업이 메인 쓰레드에서 순차적으로 실행됩니다. 요청이 오면 1개의 쓰레드를 할당한 후 서블릿 객체를 호출한 후 응답을 전달하고 휴식을 합니다. 한 번에 하나의 작업만 처리할 수 있으며, 다음 작업은 이전 작업이 완료된 후에 실행됩니다. 이러한 실행 모델은 단순하고 직관적이지만, 작업을 순차적으로 처리하기 때문에 성능이 저하될 수 있습니다.
만약 다중 요청 시 쓰레드를 하나만 사용하는데 그 하나의 쓰레드에 장애가 발생하여 처리가 지연되면, 두번째로 들어오는 요청이 대기하게되며 1번째의 요청과 2번째의 요청 모두 장애가 발생하게 될 수 있습니다. 이러한 상황을 해결하기 위해서 요청 마다 쓰레드를 생성하는 방법이 있습니다. (신규 쓰레드 생성)
💥 요청이 올때마다 쓰레드를 생성하는 경우, 동시 요청 처리가 가능하고 리소스 (CPU, 메모리)가 허용될 때까지 처리가 가능합니다. 그리고 하나의 쓰레드가 지연되어도 나머지 쓰레든느 정상 동작하는 장점이 있습니다.
하지만, 쓰레드 생성비용은 비싼편이고, 요청 마다 쓰레드를 생성하면 응답 속도가 늦어집니다. 쓰레드 생성에는 제한이 없기 때문에 고객요청이 너무 많이오면(수강신청 시) , CPU와 메모리가 버티지 못하 임계점을 넘어서 서버가 죽을 수도 있습니다.
📋 쓰레드 풀
쓰레드 풀(Thread Pool)은 쓰레드를 미리 생성하여 풀(pool)에 보관해두고, 필요할 때마다 풀에서 쓰레드를 가져와 작업을 처리하는 기법입니다. 쓰레드 풀은 다수의 클라이언트 요청을 동시에 처리해야 하는 서버 애플리케이션에서 쓰레드의 생성과 소멸에 따른 오버헤드를 줄이고 성능을 향상시키기 위해 사용됩니다.
내부에 쓰레드들을 미리 생성하여 보관하고 있다가 요청이 오게되면 쓰레드 풀로 요청을 받게되고, 풀 내부에 있던 쓰레드들을 사용하여 서블릿 객체를 호출하여 쓸 수 있습니다. 쓰레드의 사용이 다 끝나면 쓰레드 풀에 반납이 가능합니다.
- 쓰레드 재사용: 쓰레드 풀은 미리 생성된 쓰레드를 재사용하여 작업을 처리합니다. 작업이 완료되면 해당 쓰레드는 다음 작업을 처리하기 위해 풀에 반환됩니다. 이렇게 함으로써 쓰레드의 생성과 소멸에 따른 오버헤드를 줄이고, 쓰레드를 재사용함으로써 시스템의 부하를 줄일 수 있습니다.
- 제한된 쓰레드 수: 쓰레드 풀은 미리 설정된 쓰레드 개수를 가지고 있으며, 이 개수를 초과하여 쓰레드가 생성되지 않도록 관리합니다. 이를 통해 쓰레드 개수를 제한함으로써 서버의 과도한 부하를 방지하고 안정적인 성능을 유지할 수 있습니다.
- 쓰레드 생성 비용 절감: 쓰레드 풀은 미리 쓰레드를 생성하여 보관하고 있기 때문에, 새로운 작업이 들어올 때마다 쓰레드를 새로 생성하는 비용을 절감할 수 있습니다. 이는 많은 수의 작업을 처리해야 하는 경우에 특히 효과적입니다.
- 작업 대기 처리: 쓰레드 풀에 모든 쓰레드가 사용 중인 경우, 새로운 작업이 들어올 때까지 대기하게 됩니다. 이를 통해 서버의 과부하를 방지하고 안정적인 처리를 유지할 수 있습니다. (톰캣은 최대 200개 기본 설정)
쓰레드가 미리 생성되 어 있으므로, 쓰래드를 생성하고 종료하는 비용(CPU)가 절약되고 , 응답시간이 빠릅니다. 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있는 장점이 있습니다.
👉 WAS는 다수의 클라이언트로부터 동시에 여러 요청을 받을 수 있어야 하며, 이러한 요청을 동시에 처리하기 위해 멀티쓰레드를 활용할 수 있습니다. 개발자는 멀티쓰레드 관련 코드를 신경 쓰지 않아도 되고, 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스코드를 개발할 수 있습니다.
멀티 쓰레드 환경이므로 싱글톤 객체(서블릿, 스프링 빈)을 주의해서 사용해야 합니다.
📘 HTML, HTTP API, CSR, SSR이란 ?
백엔드 개발자가 서비스를 제공할 때 고려해야할 3가지 방식
- 정적 리소스 - 고정된 HTML 파일 , CSS , JS , 이미지, 영상등을 제공합니다. 주로 웹 브라우저에서 요청을 합니다. 요청이 /hello.html로 요청이 온다면, 이미 생성된 리소스 파일을 전달해줍니다.
- HTML 페이지 - WAS가 웹 브라우저에서 요청을 받으면, DB를 통해서 데이터를 조회한 후 동적으로 HTML을 생성 VIEW 템플릿인 JSP나 Thymeleaf등을 이용해서 DB에서 조회된 데이터와 프로그램 코드를 넣어서 HTML 코드를 동적으로 생성한 후 브라우저에게 전달해줍니다.
- HTTP API - DB의 데이터를 조회한 후 JSON형식의 데이터를 (KEY:VALUE) 형태의 정보를 전달하게 됩니다. 그럼 브라우저에서 해석이 바로 되진 않기때문에 브라우저에 보여주기 위해 쓰는 것이 아니라, 데이터만 주고 받는 상황에만 주로 사용됩니다.
SSR(서버 사이드 렌더링)과 CSR(클라이언트 사이드 렌더링)은 웹 애플리케이션의 렌더링 방식을 나타내는 용어입니다. 이 두 가지 방식은 웹 페이지의 내용을 브라우저에 보여주는 방식에 차이가 있습니다.
- 서버 사이드 렌더링 (SSR) → JSP , 타임리프 백엔드 개발자
서버에서 최종 HTML을 생성한 후 클라이언트에게 전달합니다. HTML을 만드는 과정을 전부 서버에서 종료 후 브라우저에 전달합니다. 서버 사이드 렌더링은 웹 서버에서 페이지의 내용을 모두 구성한 후, 클라이언트(브라우저)에게 완전히 렌더링된 HTML을 보내주는 방식입니다. 클라이언트는 렌더링된 HTML을 받아서 바로 화면에 표시할 수 있습니다. 이후에는 필요한 데이터를 요청하고 받아오는 AJAX 방식으로 동작합니다.
단점 : 서버 부하가 증가할 수 있습니다. 많은 요청을 처리해야 하므로 서버에 부담이 갈 수 있습니다. 페이지 전환이 있을 때마다 서버로부터 새로운 HTML을 받아와야 하므로 네트워크 비용이 증가할 수 있습니다
장점 : 초기 렌더링 속도가 빠르고, 첫 페이지 로딩이 빠릅니다. SEO(Search Engine Optimization)에 유리하며, 검색 엔진에서 페이지를 크롤링하기 쉽습니다. - 클라이언트 사이드 렌더링 (CSR) → React , Vue.js 프론트엔드 개발자 ****HTML결과를 자바스크립트를 사용해 웹 브라우저에서 동적으로 생성해서 적용합니다. 주로, 동적인 화면에 사용, 웹 환경을 마치 앱처럼 필요한 부분부분을 변경할 수 있습니다. 클라이언트 사이드 렌더링은 초기에 서버로부터 HTML과 필요한 JS, CSS 등의 정적 파일을 받아온 후, 클라이언트(브라우저)에서 JavaScript를 이용하여 동적으로 페이지를 구성하는 방식입니다. 클라이언트가 빈 HTML을 받아오고, 데이터를 요청한 뒤 JavaScript가 데이터를 받아와서 브라우저에 렌더링하는 방식입니다.
단점 : 초기 렌더링 속도가 느리며, 첫 페이지 로딩이 오래 걸립니다. SEO에 불리하며, 검색 엔진이 페이지를 크롤링하는 데 어려움이 있습니다.
장점 : 필요한 데이터만 요청하고 받아오므로, 서버 부하가 적습니다. 사용자 경험(UX)이 좋고, 사용자와 상호작용이 많은 웹 애플리케이션에 적합합니다.
'[ BACKEND] > Spring' 카테고리의 다른 글
[SPRING] Storage (저장소) & URL 패턴 (0) | 2023.08.03 |
---|---|
[SPRING] Servlet / HTTP Request , Response (0) | 2023.08.02 |
[SPRING] 싱글톤 방식의 주의점 💥 (0) | 2023.07.25 |
[SPRING] Web Application과 Singleton의 관계 (0) | 2023.07.24 |
[SPRING] Bean 메타 정보 ( Bean Factory & Application Context) (0) | 2023.07.23 |