0. 개요
- 이전 포스팅에서 기본적인 Web 서비스의 구조와 동작에 대해 알아보았다.
- 그리고 WAS에 대해 배우면서 WAS가 단순히 비즈니스 로직만을 수행하지 않는다는 것을 확인했다.
- 이번 포스팅에서 WAS가 비즈니스 로직 처리에만 집중하게 할 수 있도록 하는 방법에 대해 알아보자.
1. Servlet
- Servlet은 WAS가 지원하는 기능이자, 웹 서버의 성능 향상을 위한 Java의 클래스다.
- Servlet을 사용하는 이유는 WAS가 비즈니스 로직 처리만을 수행할 수 있는 환경을 제공하기 때문이다.
- 무슨 말인지 잘 모르겠다. 그러므로 Servlet의 기능과 역할에 대해 알아보자.
a) Servlet의 역할
- WAS는 웹 서버로부터 전달받은 HTTP request를 parsing 하고 다시 결과물을 HTTP response로 parsing 하는
사전/사후 처리 작업을 수행한다.
- 이러한 사전 / 사후 처리 작업으로 WAS는 비즈니스 로직을 처리하는 것에만 집중할 수 없다.
- Servlet은 WAS가 수행하는 HTTP를 처리 및 가공 작업을 대신 수행한다.
- 즉, Servlet은 WAS가 비즈니스 로직을 처리하는 것만 집중할 수 있는 환경을 제공하는 역할을 하는 것이다.
b) Servlet의 이점
- Servlet의 사용은 개발자에게도 굉장한 효율을 제공한다.
- 결국 WAS에서 HTTP 메시지를 parsing 하는 과정은 개발자가 작성해야 하는 부분이기 때문이다.
- Servlet을 사용으로 인해 개발자 또한 HTTP 메시지를 처리하는 로직을 작성할 필요가 없어진다.
- 즉, 개발자 또한 WAS의 비즈니스 로직을 작성하는 것에만 집중할 수 있게 된다.
c) Servlet의 동작원리
- WAS는 Servlet을 통해 HTTP 메시지를 기반으로 request / resposne 객체를 생성한다.
- 개발자는 Servlet 객체를 통해 HTTP 메시지 정보를 데이터처럼 사용할 수 있다.
- 위의 그림은 다음과 같은 기능을 말해준다.
- 개발자는 request 객체를 통해, HTTP 요청 정보를 데이터처럼 편하게 사용할 수 있다.
- 개발자는 response 객체를 사용하여, 데이터를 입력하듯 편하게 HTTP 응답 정보를 입력할 수 있다.
- WAS는 Servlet을 통해 개발자에게 받은 HTTP 응답 정보를 response 객체에 담아 Client에게 전달한다.
2. Servlet Container
- 위의 그림에서 Servlet Container를 확인할 수 있다.
- Servlet Container란, Servlet을 지원하는 WAS를 가리키는 말이기도 하다.
a) Servlet Container의 역할
- Servlet Container는 Servlet 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리한다.
- request, response 객체는 매번 내용이 다르기 때문에, client의 요청마다 새롭게 생성된다.
- 그러나 Servlet 객체는 request, response 객체를 처리하는 역할로 singleton으로 관리된다.
- 여기서 한 가지 특징이 있는데, Servlet은 동시 요청을 위한 멀티 thread를 지원한다는 것이다.
- thread와 Servelt은 무슨 관계가 있는 것일까?
3. Thread
a) thread의 역할
- client로부터 HTTP request가 발생하면 TCP/IP 통신이 생성되고, 이는 WAS와 연결된다.
- HTTP request가 WAS에 전달되면 Servlet 객체가 호출되는데, 이때 thread가 Servlet 객체를 호출한다.
- Thread는 application 코드를 하나씩 순차적으로 실행하는 역할을 한다.
- Java의 main() 메서드가 실행되면 main이라는 이름의 thread가 실행되면서 Java코드를 한 줄씩 읽는다.
- 이처럼 thread가 없이 Java application을 실행할 수 없다.
b) 동시 처리를 위한 멀티 thread
- 앞서 설명했듯이, thread는 한 번에 한 줄씩 코드를 실행한다.
- 하나의 요청을 처리하는데 하나의 thread가 사용되므로 동시 처리는 추가적인 thread를 필요로 한다.
- 즉, 멀티 thread를 의미한다.
c) 요청마다 thread를 생성하면 발생하는 문제점
- thread는 컴퓨터 자원 중 하나다.
- 그러므로 컴퓨터 자원의 한도 내에서 멀티 thread를 운용하며 동시 요청을 처리할 수 있다.
문제점 1) thread는 생성 비용이 비싸다.
- "비싸다"는 말은, thread를 생성하는데 필요한 컴퓨터 자원과 시간이 많이 필요하다는 뜻이다.
- 즉, 요청이 들어올 때마다 thread를 생성하는 방식은 오히려 응답 속도를 느리게 한다.
문제점 2) thread 수의 제한이 없다.
- 프로세스 하나당 CPU 코어 하나를 할당받아 처리된다.
- 그러므로 동시에 가용되는 thread의 수는 한계가 있다.
- 이 한계를 넘어서 thread를 생성하는 경우, 서버가 다운된다.
- 추가적으로 CPU에 올라가는 프로세스가 교체될 때마다 context switching의 비용이 발생한다.
- 이와 같은 문제를 어떻게 해결할까?
4. Thread Pool
- 위에서 언급한 2가지 문제점을 해결하기 위해 WAS는 thead pool을 사용한다.
- thread pool에 대해서 알아보자.
a) Thread Pool의 기능과 역할
- thread pool은 HTTP 요청이 들어오기 전에 미리 다수의 thread를 생성하여 보관한다.
- thread pool은 추가적인 thread를 생성하지 않는다.
- thread를 미리 생성해놓는 방식으로 생성할 수 있는 thread의 수를 제한한 것이다.
b) Thread Pool의 동작원리
- HTTP 요청이 들어오면 thread pool에 있는 thread를 할당받는다.
- thread는 해당 작업이 완료되는 대로 다시 thread pool로 반환된다.
- 만약 thread pool에 사용할 수 있는 thread가 없는 경우, thread를 대기하거나 요청 자체가 거절될 수 있다.
- 이는 설정에 따라 달라진다.
c) Thread Pool의 장점
- thread를 미리 생성하여 보관하기 때문에 thread 생성 비용이 절약되며, 요청에 대한 응답속도 또한 빠르다.
- 가용 thread의 수를 제한하여, thread 개수 이상의 요청이 들어와도 이미 처리 중인 요청을 안전하게 완료할 수 있다.
d) 가용 Thread의 정적 개수 찾기
- Thread Pool은 가용 thread의 개수를 제한하는 방식으로, 초기에 thread의 개수를 결정하는 것이 매우 중요하다.
- Tomcat의 경우 200개의 thread를 기본 값으로 설정하지만, 이는 서비스의 규모 / cpu 스펙 / 동시 요청 횟수 및 빈도 등
시스템 자원과 웹 서비스의 퍼포먼스를 측정하여 적정 값을 찾고 최고의 효율을 뽑아내는 것이 관건이다.
- thread의 개수를 정하는 것에 정답은 없다.
- 그러므로 실제 서비스와 유사한 상황에서 성능 test를 수행하여 예측하는 것이 중요하다.
- 성능 test를 위해서는 다양한 tool을 사용한다. ex) 아파치 ab, 제이 미터, nGrinder 등
e) WAS는 멀티 스레드를 지원한다.
- WAS는 멀티스레드에 대한 부분을 처리한다.
- 즉, 개발자는 멀티스레드 처리를 신경 쓰지 않아도 된다는 것이다.
- 그러므로 개발자는 싱글 스레드 프로그래밍을 하는 것처럼 소스 코드를 개발하면 된다.
- 다만, 멀티스레드 환경을 염두에 두고 Singleton 객체를 다룰 때에는 각별히 주의해서 사용하자.
'Back-end > Spring MVC 개념' 카테고리의 다른 글
5. JSP의 등장 (0) | 2022.02.28 |
---|---|
4. Servlet - 요청/응답 처리방법 (0) | 2022.02.25 |
3. Servlet - 기본 사용 방법 (0) | 2022.02.24 |
1. Java 웹 기술의 역사 (0) | 2022.02.22 |
0. Web 서비스의 구조 (0) | 2022.02.21 |
댓글