웹 애플리케이션 이해
웹 서버, 웹 애플리케이션 서버
- Web Server
- HTTP 기반으로 동작
- 정적 리소스 제공
- Web Application Server
- HTTP 기반으로 동작
- 웹 서버 기능 포함(정적 리소스 제공 가능)
- 동적 리소스 제공, 프로그램 코드를 실행해서 애플리케이션 로직 수행
- 웹 시스템 구성
- WAS, DB만으로 시스템 구성 가능
- WAS가 정적, 동적 리소스(애플리케이션 로직)을 모두 제공 가능하기 때문에
- 하지만 WAS만 두게 되면, 서버 과부하가 우려된다.
- 또한 장애 발생 시 오류화면 제공도 불가능하게 된다.
- 그리고 정적 리소스로 인해 애플리케이션 로직을 수행하는데 어려움이 있을 수 있다
- 그래서 Web Server와 WAS를 함께 두어 업무를 분담하는 방법을 쓴다
- 앞에서 정적리소스를 Web Server가 수행하고 애플리케이션 로직이 필요하면 WAS에 요청
- 이렇게 하면 효율적인 리소스 관리가 가능해진다
- 정적 리소스의 비중이 늘어나면 Web Server를 늘리고, 애플리케이션 리소스가 많이 사용되면 WAS를 늘리고
- 또한 서버 장애 발생시, Web Server가 WAS에 요청했는데 장애로 인해 응답이 오지 않으면, 오류화면 HTML을 제공해 줄 수 있다
서블릿
- 만약 개발자가 웹 애플리케이션 서버를 직접 구현한다고 하면
- 서버와 TCP/IP 연결 대기, 소켓 연결
- 메소드 방식, URL 매핑
- content-type 확인
- http 메시지 바디 내용을 파싱
- 저장 프로세스를 실행
- 비즈니스 로직 수행
- DB와 연결
- http 응담 메시지 생성
- TCP/IP에 응답 전달, 소켓 종료
- 같은 작업들을 수행해야 한다.
- 이 과정에서 비즈니스 로직을 제외한 나머지 로직들은 일관성이 있다.
- 따라서 서블릿을 지원하는 WAS를 사용하게 되면
- 비즈니스 로직을 제외한 과정을 서블릿이 수행하여 준다
- @WebServlet(name=”abcd”, urlPatterns=”/efg”)
- 매개변수로 HttpServletRequest request, HttpServletResponse response
- 개발자는 HTTP 스펙을 편리하게 사용할 수 있다.
- 서블릿 HTTP 요청, 응답 흐름
- WAS는 Request, Response 객체를 새로 만들어서 서블릿 객체 호출
- 개발자는 Request 객체에서 http 요청 정보를 편리하게 꺼내서 사용
- 개발자는 Response 객체에서 http 응답 정보를 편리하게 입력
- WAS는 Response 객체에 담겨있는 내용으로 http 응답 정보를 생성
- 서블릿 컨테이너
- 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 한다
- 서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리한다
- 서블릿 객체는 싱글톤이다
- 고객의 요청이 올 때마다 계속 객체를 생성하는 것은 비효율적이다
- 최초 로딩 시점에서 서블릿 객체를 미리 만들어두고 재활용한다
- 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근한다
- 따라서 공유 변수 사용에 주의하여야 한다
- 서블릿 컨테이너 종료 시 함께 종료된다
- JSP도 서블릿으로 변환 되어서 사용된다
- 동시 요청을 위한 멀티 쓰레드 처리를 지원한다
동시 요청 - 멀티 쓰레드
- 쓰레드
- 클라이언트에서 요청이 오면, WAS랑 연결을 하고, 서블릿을 호출하는데, 서블릿은 누가 호출하는걸까? 이게 바로 쓰레드이다.
- 애플리케이션 코드를 하나하나 순차적으로 실행하는 것은 쓰레드이다
- 자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 실행된다
- 쓰레드가 없다면 자바 애플리케이션은 실행이 불가능하다
- 쓰레드는 한번에 하나의 코드 라인만 수행한다
- 동시 처리가 필요하면 쓰레드를 추가로 생성한다
- 단일요청 -쓰레드를 하나만 사용
- 요청이 오면 WAS는 연결하고, 쓰레드를 할당한다.
- 쓰레드는 서블릿을 호출하고 데이터 처리 후 응답하여 클라이언트에게 보낸다
- 쓰레드는 휴식을 취한다
- 다중요청 - 쓰레드 하나 사용
- 클라이언트1에서 요청이 들어오면 쓰레드를 할당하고 서블릿을 호출하여 로직 실행
- 클라이언트1의 요청에 따른 서블릿의 처리에서 지연이 발생
- 클라이언트2의 요청이 들어옴
- 서블릿이 하나이기 때문에 클라이언트1의 요청이 완료되어 쓰레드가 휴식이 될때까지 대기
- 시간이 많이 지연되면 둘다 타임아웃 오류발생
- 해결?
- 요청이 들어올 때마다 새로운 쓰레드를 생성하여 배정
- 요청 처리후 쓰레드 제거
- 요청마다 쓰레드를 생성 시
- 장점
- 동시 요청 처리 가능
- 리소스(CPU, 메모리)가 허용할 때 까지 처리 가능
- 하나의 쓰레드가 지연되어도, 나머지 쓰레드는 정상 동작한다
- 단점
- 쓰레드는 생성 비용이 비싸다
- 따라서 고객 요청 마다 쓰레드를 생성하면, 생성 시 시간이 소요가 되기 때문에 응답속도가 느려진다
- 쓰레드는 컨텍스트 스위칭 비용이 발생한다
- 쓰레드 생성에 제한이 없다
- 따라서 고객 요청이 너무 많으면 CPU, 메모리의 임계점을 넘어서 서버가 죽을 수 있다
- 컨텍스트 스위칭 비용
- 하나의 CPU는 하나의 쓰레드를 처리한다.
- 멀티 쓰레드라면 하나의 쓰레드를 처리하고 대기 시간동안 다른 쓰레드로 이동하여 로직을 수행한다.
- 쓰레드에서 쓰레드로 옮길 때 발생하는 비용이 컨텍스트 스위칭 비용이다.
- 즉, 요청된 쓰레드가 많으면 쓰레드와 쓰레드 사이의 이동 시 많은 비용이 발생한다
- 장점
- 쓰레드 풀
- 필요한 쓰레드를 쓰레드 풀에 보관하고 관리
- 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. 갯수는 변경 가능하다.
- 톰캣은 최대 200개로 기본 설정이 되어 있다
- 사용
- 요청 시 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내서 사용
- 사용 종료 시 쓰레드 풀에 쓰레드 반납
- 최대 쓰레드가 모두 사용중인데 요청이 오면
- 요청을 거절하거나 특정 숫자만큼 대기하도록 설정 가능
- 장점
- 쓰레드가 미리 생성되어 있으므로, 쓰레드를 생성하고 종료하는 비용(CPU)가 절약되고, 응답시간이 빨라진다
- 생성 가능한 쓰레드의 최대치가 정해져 있으므로 너무 많은 요청이 들어와도 서버가 죽는 일이 없다
- 쓰레드 풀의 실무 팁
- WAS의 주요 포인트는 최대 쓰레드(mat thread) 수이다
- 이 값을 너무 낮게 설정하면
- 동시 요청이 많으면, 서버 리소스는 여유롭지만, 클라이언트는 금방 응답 지연을 받는다
- 예를들어 CPU가 5% 밖에 사용되지 않는데 요청이 많으니 클라우드 서버를 추가 증원하고 추가 비용이 발생하게 된다.
- 너무 높게 설정
- 동시 요청이 많을 시 CPU, 메모리 리소스 임계점의 초과로 서버 다운 발생
- 장애 발생 시
- 일단 클라우드 서버부터 늘리고, 이후에 맥스 쓰레드의 적정 수치를 찾는 튜닝
- 쓰레드 풀의 적정 숫자
- 애플리케이션의 로직의 복잡도(DB를 몇번이나 연결하느냐), CPU, 메모리, IO 리소스 상황에 따라 모두 다르다
- 성능 테스트
- 최대한 실제 서비스와 유사하게 성능 테스트를 시도한다
- 도구 : 아파치 ab, 제이미터, nGrinder(네이버 오픈소스, 추천)
- WAS의 멀티 쓰레드 지원
- 멀티 쓰레드에 대한 부분은 WAS가 처리
- 개발자는 멀티 쓰레드와 관련된 코드를 신경쓰지 않아도 된다
- 멀티 쓰레드 환경이므로, 싱글톤 객체(서블릿, 스프링 빈)는 주의해서 사용하자
HTML, HTTP API, CSR, SSR
- 정적 리소스
- 고정된 HTML 파일, CSS, JS, 이미지, 영상 등을 제공하면 된다
- 주로 웹 브라우저
- HTML 페이지
- 동적으로 필요한 HTML 파일을 생성해서 전달
- 웹 브라우저 : HTML을 해석
- WAS가 DB를 통해 데이터를 받고, 동적으로 HTML을 생성
- view template라고 하는 jsp, 타임리프 같은 것이 해당
- 생성된 HTML을 브라우저에게 전달
- HTTP API
- HTML이 아니라 데이터를 전달
- 주로 JSON 형식을 사용
- 다양한 시스템에서 호출
- 브라우저 요청, WAS에서 DB에 데이터 요청, DATE를 브라우저에게 그대로 전달
- 예를들어
- 웹 클라이언트 to 서버 : JS에서 데이터 처리하여 html을 동적으로 생성하여 랜더링, ajax 또는 vue.js, React 같은 웹클라이언트
- 앱 클라이언트 to 서버
- 서버 to 서버 : MSA, 기업간 데이터 통신
- SSR(서버사이드 랜더링)
- HTML 최종 결과를 서버에서 만들어서 웹 브라우저에게 전달
- 주로 정적인 화면에 사용
- 관련기술 : JSP, 타임리프
- 백엔드 개발자
- 자바스크립트를 사용해서 화면 일부를 동적으로 변경 가능하다
- CSR(클라이언트 사이드 랜더링)
- HTML 결과를 JS를 사용하여 웹 브라우저에서 동적으로 생성해서 적용
- 주로 동적인 화면에 사용, 웹 환경을 마치 앱 처럼 필요한 부분부분 변경할 수 있다
- 예) 구글 지도, Gmail, 구글 캘린더
- 관련기술 : React, Vue.js
- 웹 프론트 엔드 개발자
- CSR + SSR 동시에 지원하는 웹 프레임워크도 있다.
출처
- 인프런의 김영한님의 강의를 듣고 정리한 것입니다.