Tomcat Thread Pool 정리

devdo·2022년 11월 2일
1

JSP/Servelt

목록 보기
1/2

Thread란?

실행중인 프로그램을 프로세스라 부르고, 그 프로세스의 실행단위가 스레드이다.

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

작업관리자창에서 프로세스에 대한 스레드를 확인할 수도 있다.

나오게 하는 방법 - 자세히 > 오른쪽 클릭 > 열선택 > 스레드 클릭 하면 나타난다.

그래서 스레드가 많아지면 프로그램 내에서 할 수 있는 것들이 많아져

스레드가 많으면 많을수록 좋은 것이 아닌가? 이렇게 생각할 수 있다.

하지만 스레드가 생성되면서 비용이 들어간다는 것을 잊으면 안된다!

컨텍스트 스위칭이 일어나 Memory Leak(메모리 누수)이 생기고 그러면서 cpu 오버헤드 비용이 든다.

즉, 스레드는 생성비용이 상당히 크다. 그러면서 요청에 대한 응답시간이 늘어날 가능성이 커지는 것이다.

그 과정을 보면,

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

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

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

그래서 Thread 생성비용이 많이 드는 것이다.

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

자, 그러니 Thread를 너무 많이 생성하면! 상당한 문제가 있다는 것을 알게 되었다.


Thread Pool이란?

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

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

자 결론,

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


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)


참고

profile
배운 것을 기록합니다.

1개의 댓글

comment-user-thumbnail
2022년 11월 19일

좋은 글 감사합니다 늘 잘보고있습니다 :)

답글 달기