우아한 테크코스 스레드 퀘스트를 수행하다보니 궁금한 점이 생겼다.
웹 애플리케이션에서 수많은 사용자가 동시에 우리 서버에 요청을 보낼 때, 스프링은 어떻게 이 모든 요청을 효율적으로 처리하는 걸까? 그 비밀은 바로 톰캣(Tomcat)의 스레드 풀과 연결 관리 설정에 있다.
오늘은 application.yml
파일에서 설정할 수 있는 톰캣의 핵심 설정 세 가지를 톰캣 공식 문서를 바탕으로 분석한 결과를 써보려고 한다.
먼저 스프링 부트 프로젝트의 study/src/main/resources/application.yml
파일을 찾아보자. 이 파일에서 톰캣의 성능과 안정성을 결정하는 중요한 설정들을 확인할 수 있다.
server:
tomcat:
accept-count: 1
max-connections: 1
threads:
max: 2
톰캣 공식 문서 원문:
The maximum length of the operating system provided queue for incoming connection requests when maxConnections has been reached. The operating system may ignore this setting and use a different size for the queue. When this queue is full, the operating system may actively refuse additional connections or those connections may time out. The default value is 100
한글 번역 및 분석:acceptCount
는 maxConnections
에 도달했을 때 들어오는 연결 요청을 위한 운영체제 제공 대기열의 최대 길이를 의미한다. 운영체제는 이 설정을 무시하고 대기열에 다른 크기를 사용할 수도 있다. 이 대기열이 가득 차면 운영체제는 추가 연결을 적극적으로 거부하거나 해당 연결이 타임아웃될 수 있다. 기본값은 100이다.
의미:
톰캣 공식 문서 원문:
The maximum number of connections that the server will accept and process at any given time. When this number has been reached, the server will accept, but not process, one further connection. This additional connection be blocked until the number of connections being processed falls below maxConnections at which point the server will start accepting and processing new connections again. Note that once the limit has been reached, the operating system may still accept connections based on the acceptCount setting. The default value is 8192.
For NIO/NIO2 only, setting the value to -1, will disable the maxConnections feature and connections will not be counted
한글 번역 및 분석:
서버가 주어진 시간에 수락하고 처리할 수 있는 최대 연결 수를 의미한다. 이 숫자에 도달하면 서버는 추가 연결 하나를 더 수락하지만 처리하지는 않는다. 이 추가 연결은 처리 중인 연결 수가 maxConnections
아래로 떨어질 때까지 차단되며, 그 시점에서 서버는 새로운 연결을 다시 수락하고 처리하기 시작한다. 한계에 도달하면 운영체제는 여전히 acceptCount
설정에 따라 연결을 수락할 수 있다는 점을 주의해야 한다. 기본값은 8192이다.
NIO/NIO2에서만 값을 -1로 설정하면 maxConnections
기능이 비활성화되고 연결이 카운트되지 않는다.
의미:
톰캣 공식 문서 원문:
The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled. If not specified, this attribute is set to 200. If an executor is associated with this connector, this attribute is ignored as the connector will execute tasks using the executor rather than an internal thread pool. Note that if an executor is configured any value set for this attribute will be recorded correctly but it will be reported (e.g. via JMX) as -1 to make clear that it is not used.
한글 번역 및 분석:
이 커넥터가 생성할 요청 처리 스레드의 최대 개수로, 따라서 동시에 처리할 수 있는 최대 요청 수를 결정한다. 지정되지 않으면 이 속성은 200으로 설정된다. 이 커넥터에 실행자(executor)가 연결되어 있으면 커넥터가 내부 스레드 풀이 아닌 실행자를 사용하여 작업을 실행하므로 이 속성은 무시된다. 실행자가 구성되어 있으면 이 속성에 설정된 값은 정확히 기록되지만 사용되지 않는다는 것을 명확히 하기 위해 (예: JMX를 통해) -1로 보고된다는 점을 주의해야 한다.
의미:
threads.max
는 "얼마나 많은 스레드로 동시에 처리할 수 있냐"max-connections
는 "동시에 유지할 수 있는 연결 수"accept-count
는 "스레드 다 차면 몇 개까지 대기열에 둘 수 있냐"
이제 이 세 설정이 어떻게 협력하여 다중 사용자 요청을 처리하는지 살펴보자.
1단계: 연결 수락
maxConnections
한계 내에서 연결을 수락한다2단계: 대기열 관리
maxConnections
에 도달하면 acceptCount
크기만큼 대기열에서 대기한다3단계: 요청 처리
maxThreads
범위 내에서 스레드를 할당한다4단계: 자원 반환
퀘스트의 전달한 핵심 가치가 마지막에 적혀져 있었다.
📚 이것이 WAS 스레드풀에서 의미하는 것
- WAS는 무제한으로 요청을 받아들이지 않는다.
- WAS는 정해진 규칙에 따라 자원을 할당한다.
- 이러한 설정은 서버가 과부하로 인해 죽지 않도록 보호하는 핵심 메커니즘이다.
- 실무에서는 대용량 트래픽 상황에서 이 설정들이 사용자 경험과 서비스 안정성을 좌우하는 중요한 요소가 된다.