이번 장에서는 Tomcat의 구조에 대해 살펴보겠습니다. 새로운 용어들이 많아서 낯설 수도 있습니다. 차근차근 알아가보겠습니다.
Tomcat을 구성하는 큰 단위로는 다음의 3가지가 있습니다.
• Coyote (HTTP Component) : Tomcat에 TCP를 통한 프로토콜 지원
• Catalina (Servlet Container) : Java Servlet을 호스팅하는 환경
• Jasper (JSP Engine) : 실제 JSP 페이지의 요청을 처리하는 Servlet
3가지의 구성요소는 다음과 같이 동작합니다.
위의 3가지 구성요소는 다음의 5단계 구조에 포함됩니다. 더 자세한 내용은 아래 Tomcat 구조
를 통해 살펴보도록 하겠습니다.
Tomcat 은 Java로 작성된 Program이기 때문에 JVM (Java Virtual Machine) 위에서 동작합니다. 하나의 JVM 에서 하나의 Tomcat Instance (Server)가 하나의 Process 로써 동작합니다.
하나의 Server 에는 여러 개의 Service 가 존재할 수 있습니다. 각각의 Service는 1개의 1개의 Engine 과 여러 개의 Connector 로 구성됩니다.
Engine 은 Catalina Servlet Engine이라고도 불리며, 정의된 Connector로 들어온 요청을 하위에 있는 해당 Host에게 전달해주는 역할을 수행합니다.
하나의 Engine 에는 여러 개의 Host 가 존재할 수 있습니다. Host는 가상호스트 이름을 나타내며, 호스트 이름이 곧 url에 매핑됩니다. (ex : http://hostname/ ).
하나의 Host 에는 여러 개의 Context 가 존재할 수 있습 니다. Context는 하나의 Web Application을 나타내며 주로 *.war 파일의 형태로 배포가 됩니다.
Tomcat Server가 요청을 받으면, Catalina (Tomcat Engine)가 요청에 맞는 Context (Context path)를 찾고, Context는 자신이 설정된 어플리케이션의 deployment descriptor file (web.xml)을 기반으로 전달받은 요청을 서블릿에게 전달하여 처리되도록 합니다.
즉, 클라이언트 HTTP request > Catalina > Context > Servlet > 클라이언트 response 순으로 처리됩니다.
아래는 Tomcat의 5-tier architecture를 나타낸 그림입니다. 각 tier마다 설정해야 할 parameter들과 설명들 도 일부 작성하였습니다. (설정을 한다는 것은, CATALINA HOME/conf/server.xml에서 값을 수정하는 것을 뜻합니다.)
Connector 는 TCP port에서 request들을 listen하여 해당 Engine으로 보내주는 역할을 수행하며 3가지의 종류가 있습니다.
• HTTP/1.1 과 HTTP/2 Connector 는 Tomcat이 standalone web server로 동작하거나 다른 web server의 요청을 받아 WAS의 역할을 수행하도록 지원해줍니다.
• AJP Connector 는 Apache HTTP Web server의 요청을 처리하기 위한 특수한 Protocol을 처리합니다.
Connector마다 동작하는 방식을 설정할 수 있습니다. 동작하는 방식으로는 BIO, NIO, NIO2, APR
로 총 4 종류가 있습니다. (Tomcat 버전별로 지원하는 동작방식이 상이합니다.)
• BIO : Tomcat 7의 기본방식이며, 하나의 thread가 하나의 connection을 담당하는 것입니다. 레스토랑으로 생각해보자면, 한명의 종업원이 하나의 손님 그룹 (하나의 테이블)을 전담하는 것으로 비유 할 수 있습니다.
maxConnections = maxThreads = 200 이라는 기본 값으로 설정됩니다.
• NIO : Tomcat 8.5 부터의 기본방식이며, 하나의 thread가 하나 이상의 connection을 담당하는 것입니다. 레스트랑으로 생각해보자면, 한명의 종업원이 여러 손님 그룹을 위해 주문을 받거나 서빙하는 등의 업무를 수행하는 것으로 비유할 수 있습니다.
maxConnections는 default가 10,000 이고, maxThreads는 default가 200입니다.
• APR : Apache Portable Protocol 이라는 특수한 Protocol입니다.
maxConnections는 default가 8,192 입니다. https://github.com/apache/tomcat/blob/master/TOMCAT-NEXT.txt 을 보면, 10.x 버전부터는 APR 방식이 삭제된다고 합니다.
사용할 Protocol을 지원하는 Connector를 선정하고 그 후 해당 Connector의 동작방식을 선택하고 나면 반드시 고려해야 할 parameter 들은 다음과 같습니다. (위에서 일부 언급된 내용입니다)
• maxThreads : Connector가 생성할 수 있는 최대 Thread 수 (Active user 수를 의미합니다) (default = 200), Connector를 Executor (Shared Thread Pool)로 설정했다면 값이 무시됨.
• maxConnections : 동시 처리 가능한 최대 Connection 수 (현재 사용중인 fd의 수) (default) BIO는 maxThreads 값과 동일, NIO = 10,000, ARP = 8,192
• maxSpareThreads : 최소로 실행을 유지할 thread 수 (default = 10)
• acceptCount : 모든 thread가 사용 중일때, queue에 저장 가능한 최대 request 수 (backlog를 의미합니 다)
(default = 100)
각 Connector로 들어온 요청은 Thread pool에서 할당된 thread 가 담당합니다. 배정된 thread는 context path로 찾은 해당 web.xml에게 서블릿 작업 처리요청을 하고 다시 응답받을 때까지 대기합니다. 서블릿 응답을 받은 thread는 다시 돌아와 클라이언트에게 response를 전달하고 다시 Thread pool에 반환됩니다.
Thread Pool 은 Dedicated Thread Pool과 Shared Thread Pool가 있습니다. Dedicated Thread Pool은 Connector마다 개별적인 Thread Pool을 가지는 것이고, Shared Thread Pool은 Engine에 할당된 여러 개의 Connector가 공유하는 Thread Pool을 뜻합니다. 실제 운영환경에서는 Dedicated Thread Pool을 주로 사용합 니다.
다음 장에서는 Tomcat의 설정파일들과 JDBC에 대해 알아보겠습니다.
잘봤습니다!