코딩공부/백엔드개발 공부

[Spring Boot] Spring Boot 내장 Tomcat의 thread pool 설정

내일의기대 2023. 12. 14. 02:42

본 글에서는 Spring Boot 내장 Tomcat thread pool 설정과 현재 톰캣 thread 개수를 간단하게 모니터링 하는 방법을 간단하게 설명합니다. tomcat thread pool 설정은 application.properties를 통해서 그리고 모니터링은 actuator를 통해 진행합니다.

1. 설정

- maven 설정
actuator와 starter-web dependency를 추가하였습니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

- application.properties 
아래는 tomcat thread pool과 모니터링 관련 설정입니다. thread pool 관련 적혀있는 값은 디폴트 값입니다.

#server port
server.port=18080

##tocmat thread pool 설정
# 생성할 수 있는 thread의 최대 개수
server.tomcat.threads.max=200

# 항상 활성화 되어있는(idle) thread의 개수. 다른말로 core size
server.tomcat.threads.min-spare=10

# connection의 최대 개수
server.tomcat.threads.max-connections=8192

# 작업큐 사이즈
server.tomcat.threads.accept-count=100


##모니터링 관련 설정
# actuator가 tomcat thread 현황을 읽어갈 수 있도록 셋팅
server.tomcat.mbeanregistry.enabled=true

#actuator의 metrics에 접근할 수 있게 설정합니다.
management.endpoints.web.exposure.include=metrics

여기서 설정을 보면 server.tomcat.threads.max는 tomcat이 만들 수 있는 최대 max thread 개수 입니다.
server.tomcat.threads.min-spare는 기본적으로 생성하고 있는 core thread 개수입니다. 아무것도 하지 않아도 10개를 유지한다는 의미입니다.
server.tomcat.thread.max-connections는 연결 가능한 최대 connection 개수 입니다. 그리고 바로 아래 있는 accept-count는 max-connection이 가득차도 추가적으로 가지고 있을 수 있는 queue size를 의미합니다.

acceptCount, maxConnections, 그리고 maxThreads의 관계. 출처 adservio.fr (그림 클릭 시 연결)

따라서 request가 들어오면 기본적으로 min-spare 개수의 thread가 처리를 하는데, 만약 요청의 개수가 현재 thread의 개수보다 커지면 thread가 max 값까지 증가합니다. max 값을 넘으면 thread를 더 증가시키지는 않고 위 그림의 maxConnections queue에서 대기를 합니다. 그리고 thread의 작업이 끝나면 대기하고 있는 요청을 할당해 줍니다.
최근 Tomcat에서는 사용하는 NIO Connector는 요청마다 하나의 thread는 만들지는 않다고 하는데 이 부분은 아직 이해를 하지 못하여 다른글을 참조하시기 바랍니다. (NIO Connector 설명글 링크)

2. 테스트

요청을 받으면 20초를 sleep하여 부하를 주는 controller를 만들어서 thread가 어떻게 증가하는지 테스트 해보겠습니다.
controller는 아래와 같이 만들었습니다.

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @GetMapping(value = "/demo")
    public String demoController() throws InterruptedException {
        Thread.sleep(20000);
        return "this is thread monitoring demo";
    }
}

그리고 application.properties의 설정을 다음과 같이 수정하였습니다.

##tocmat thread pool 설정
# 생성할 수 있는 thread의 최대 개수
server.tomcat.threads.max=20

# 항상 활성화 되어있는(idle) thread의 개수. 다른말로 core size
server.tomcat.threads.min-spare=10


프로그램을 실행하여 http://localhost:18080/actuator/metrics/tomcat.threads.current 에 접속한 결과는 다음과 같습니다.

현재 min-spare 개수만큼의 thread가 있는 것을 알 수 있습니다. 이 상태에서 요청을 30번 이상 했을 경우 아래와 같이 max 이상으로 thread를 만들지 않는 결과를 볼 수 있습니다.

시간이 지나면 다시 thread 개수가 10으로 돌아오는것 또한 확인하였습니다.

3. 결론
이번글에서는 tomcat thread pool의 설정을 바꾸는 방법을 알아보고 간단하게 모니터링한 결과를 보여드렸습니다.
하지만 본 글을 쓸때 Tomcat Connector에 대한 이해가 없는 상태로 써서 정확한 작업 처리 동작을 알기는 힘들었습니다.
추후 Tomcat의 NIO Connector에 대한 이해와 prometheus와 같은 모니터링 툴을 이용하여 시각화 해볼 계획입니다.

참고자료

- sihyung92님의 블로그 https://sihyung92.oopy.io/spring/1

 

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

개요

sihyung92.oopy.io

- https://stackoverflow.com/questions/57572370/monitoring-springboot-2-0-tomcat-server-thread-utilization- 

 

Monitoring Springboot 2.0 Tomcat server Thread utilization

I have started my springboot application with following tomcat parameters -Dserver.tomcat.max-threads=400 -Dserver.tomcat.max-connections=4000 I want to monitor busy thread and busy connection si...

stackoverflow.com