톰캣

2022. 12. 31. 21:51카테고리 없음

쓰레드 

 

 

쓰레드는 커넥터에 종속이된다,

 

connector안에 쓰레드가 들어가 있고 

8080프로토콜과 포트를 사용해서 리슨하는 커넥터는 기본적으로 쓰레드 속서이 들어가 있다.

 

sharedExcuter 를 사용해서 상속을 바아서 하나의 쓰레드 풀에서 관리를 한다.

 

톰캣은 자바기반의 서블릿 컨테이너 로서 java웹 어플리케이션 표준인 jsp /서블릿을 개발 한다,

오로지 서블릿 /jsp 및 http 처리 엔진만 들어있따.

 

톰캣 (Tomcat)이란?

dynamic(동적)인 웹을 만들기 위한 웹 컨테이너, 서블릿 컨테이너라고 불리며, 웹서버에서 정적으로 처리해야할 데이터를 제외한 JSP, ASP, PHP 등은 웹 컨테이너(톰캣)에게 전달한다.

  • WAS(Web Application Server)
  1. 컨테이너, 웹 컨테이너, 서블릿 컨테이너라고 부름
  2. JSP,서블릿처리,HTTP요청 수신 및 응답
  3. 아파치만 쓰면 정적인 웹페이지만 처리하므로 처리속도가 매우 빠르고 안정적이다.

하지만 톰캣(WAS)를 쓰면 동적인 데이터 처리가 가능하다. DB연결,데이터 조작, 다른 응용프로그램과 상호 작용이 가능하다. 톰캣은 8080포트로 처리한다.




아파치톰캣 (Apache+Tomcat)

톰캣이 아파치의 기능 일부를 가져와서 제공해주는 형태이기 때문에 같이 합쳐서 부른다. WAS(Web Application Server)

 

그림을 통해서 아파치와 톰캣의 차이를 알 수 있다. 톰캣은 일반적으로 WAS(Wep)라고 불리며, 톰캣은 아파치와 합쳐서 아파치톰캣 이라 부른다.

  1. 아파치만 사용하면 정적인 웹페이지만 처리 가능
  2. 톰캣만 사용하면 동적인 웹페이지 처리가 가능하지만 아파치에서 필요한 기능을 못가져옴. 또한 여러 사용자가 요청할시에 톰캣에 과부하가 걸림.
  3. 아파치와 톰캣을 같이 쓰면 아파치는 정적인 데이터만 처리하고, JSP 처리는 Web Container(톰캣의 일부)로 보내주어 분산처리 할 수 있다.

아파치 : 80포트
톰캣 : 8080포트
(하지만 실제로는 80포트로 다 처리하므로, 8080포트는 아파치가 알아서 보내줌. 8080포트를 다루거나 보려면 리눅스단에서 처리하거나 수동적으로 포트 처리할때 빼고는 보기힘듬)




아파치 톰캣 정리

 

아파치와 톰캣은 멀티 프로세스인가 멀티 쓰레드 인가?

 

아파치는 정적인 데이터를 처리하는 웹 서버로, 기본적으로 멀티 프로세스 구현 되어있습니다.

하지만 설정 에 따라 멀티 쓰레드를 같이 운용 할수 있습니다 .

 

톰캣은 웹 어플리케이션 서버로 , 요청을 처리하기 위한 Thread Pool을 관리하며 요청이 오면 Thread Pool 내에 쓰레드를 제공하여 요청을 처리 하도록 합니다.

즉 , 멀티 쓰레드를 제공합니다.

 

 

톰캣 쓰레드 풀?

Thread는 생성비용이 커 너무 많이 만들어 두면 위험하다. 그래서 이를 해결하기 위한 아이디어가 Pool이다. 미리 Thread를 만들어두어 재사용할 수 있게 하는 것이다.

그리고 사용할 Thread 개수를 제한하기 때문에 무제한적으로 스레드가 생성되지 않아서 방지도 가능하다.

질문1 쓰레드가 많으면 좋은게 아닌가?

실행중인 프로그램을 프로세스라 부르고, 그 프로세스의 실행단위가 스레드이다.
컴퓨터 CPU core가 사실, Thread 단위로 작업을 처리한다.
그리고 프로그램이 돌아가면서 여러가지 작업을 동시에 할 수 있는 것이 스레드이다.

그래서 스레드가 많아지면 프로그램 내에서 할 수 있는 것들이 많아져 스레드가 많으면 많을수록 좋은 것이 아닌가? 이렇게 생각할 수 있다.

하지만 스레드가 생성되면서 비용이 들어간다.

컨텍스트 스위칭이 일어나 메모리 릭이 생기고 그러면서 cpu 오버헤드 비용이 든다. 즉,
스레드는 생성비용이 상당히 크다. 그러면서 요청에 대한 응답시간이 늘어날 가능성이 커진다.

그 과정을 보면,

Java는 One-to-One Threading-Model로 Thread를 생성한다.

User Thread(Process의 스레드) 생성시
OS Thread(OS 레벨의 스레드) 와 연결해야 한다.

새로운 Thread를 생성할 때마다 OS Kernel의 작업이 필요하다.

Thread는 생성비용이 많이 든다.

작업 요청이 들어올 때마다 Thread를 생성하면 최종적인 요청 처리 시간이 증가하는 것이다.

자, 그러니 Thread가 너무 많아지면 상당한 문제가 있다는 것을 알게된다.

 

 

여러개의 작업을 동시에 처리하면서도 안정적으로 처리하고 싶은 때 Thread Pool은 효과적이다.

 

a. 각 요청에 대해 쓰레드를 생성하여 사용하고 난 후 계속해서 재사용할
   수 있도록 사용된 쓰레드를 "open" 상태로 계속 유지하며 이를 관리한
   다. 관리되고 있는 쓰레드는 소멸되지 않고 계속 "open" 상태로 유지
   되고 있다가 다른 요청이 들어오면 관리되고 있는 쓰레드를 사용하여
   해당 요청을 처리하도록 한다. 다시 요청을 처리하고 난 쓰레드는 관리
   대상이 되어 관리되어 지며 또 다른 요청을 기다린다.
   
b. 이러한 방식은 각 요청에 대해 쓰레드를 생성하고 사용한 후 소멸되는
   반복적인 절차를 탈피하게 하며, 반복적인 쓰레드의 생성 및 소멸로
   인해 야기되는 문제를 해결한다.

c. Tomcat 3.2 부터는 Tomcat의 Admin이 단지 server.xml 파일에 Thread
   Pool 에 대한 설정만으로 위의 사항을 해결할 수 있도록 하며, 자신의
   사이트에 맞도록 쓰레드의 제한 사항등을 조정할 수 있게 한다.

d. 동시에 사용할 수 있는 쓰레드의 상한선, idle 상태의 쓰레드에 대한
   최대 쓰레드 갯수 및 톰캣 기동시 생성될 최소한의 쓰레드 수를 설정
   할 수 있다.

=> ThreadPool은 동시 사용가능한 150개의 thread를 생성 할수 있고 최초 풀 생성시 4개 쓰레드로 (minSpareThreads)상태로 시작하며 최소한 4개의 쓰레들 이상을 유지한다.

 

Thread Pool을 활용한 WAS,Tomcat 

 

  • SpringBoot 의 내장 Servelt 컨테이너 중 하나
    Servelt 컨테이너의 자세한 내용은 다음 블로그를 참조 - https://velog.io/@mooh2jj/WAS는-서블릿-컨테이너
  • SpringBoot 최신 버전에는 Tomcat9 버전을 사용중
  • Java 기반의 WAS
  • Java의 Thread Pool 클래스와 매우 유사한 자체 스레드 출 구현체를 가지고 있다.

스레드풀을 자바에서 구현한 구현체가 ThreadPoolExecutor이다.

org.apache.tomcat.util.threads.ThreadPoolExecutor

 

스레드풀 생성(ThreadPoolExecutor)

application.yml

server:
  tomcat:
    threads:
      max: 200 # 생성할 수 있는 thread의 총 개수
      min-spare: 10 # 항상 활성화 되어있는(idle) thread의 개수
    accept-count: 100 # 작업 큐의 사이즈

1) Max-Connections
: Tomcat이 최대로 동시에 처리할 수 있는 Connection의 개수

Web 요청이 들어오면 Tomcat의 Connector가 Connection 을 생성하면서 요청된 작업을 Thread Pool의 Thread에 연결한다.

2) Accept-Count
: Max-Connections 이상의 요청이 들어왔을 때 사용하는 대기열 Queue의 사이즈
Max-Connections와 Accept-Count 이상의 요청이 들어왔을 때 추가적으로 들어오는 요청은 거절 될 수 있다.

이 두가지 설정은 스레드 최대 사이즈 및 core size 를 변경할 수 있도록 해줍니다. 톰캣 9.0의 디폴트 옵션은 각각 200개, 25개 인데 스프링부트(ServerProperties)에선 200개, 10개를 디폴트 값으로 잡았습니다.

 

어떻게 Tomcat 설정을 하면 어플리케이션 설계를 잘 할 수 있을까?

  • server.tomcat.threads.max
    : Thread Pool에서 사용할 최대 스레드 개수, 기본값은 200
  • server.tomcat.threads.min-spare
    : Thread Pool에서 최소한으로 유지할 Thread 개수, 기본값은 10
  • server.tomcat.max-connections
    : 동시에 처리할 수 있는 최대 Connection 의 개수, 기본값은 8192
    : 사실상 서버의 실질적인 동시 요청처리개수라고 생각할 수 있다.
  • server.tomcat.accept-count
    : max-connections 이상의 요청이 들어왔을 때 사용하는 요청 대기열 Queue 의 사이즈 기본값은 100
    : 부적절한 요청들을 필터링하는 데 필요!

☘ 서버 어플리케이션의 품질은 동시에 처리할 수 있는 요청 개수와 관련있다.

잘못된 설정으로 생겨날 수 있는 시나리오는 2가지이다.

1) 요청수에 비해 너무 많게 설정 -> 놀고 있는 스레드가 많아져 메모리,cpu 자원 비효율 증대
2) 너무 적게 설정 -> 동시 처리 요청수가 줄어든다. 평균응답시간, TPS 감소

  • Non-Blocking IO에서는 최대 Thread 개수보다 적거나 같은 수의 connections을 설정하면 비효율적인 설정이 될 수 있다. (tomcat8 이후 버전에서는 Non-blocking IO이며, N Connection-1Thread)

스프링부트는 어떻게 다중 유저 요청을 처리할까? (Tomcat9.0 Thread Pool) (oopy.io)