Spring Boot 를 사용하다보면 내장 톰캣을 Servlet Container 로 사용하여 웹 요청을 처리할 수 있다고 합니다. Tomcat 은 또한 다중 요청을 처리하는데, 이는 Thread Pool 을 통해 구현되어 있습니다.
Tomcat 은 Java 로 만들어져 있기 때문에 Java Thread Pool 을 사용합니다.
때문에 Tomcat 을 이해하기 위해선 Java Thread Pool 에 대한 이해가 필수적입니다.
org.apache.tomcat.embed:tomcat-embed-core:9.0.64
- apache
- catalina
- core
- StandardServer.java
- startup
- Tomcat.java
- core
- coyote
- http11
- Http11NioProtocol.java
- http11
- juli
- naming
- tomcat
- catalina
Tomcat 이 사용하는 StandardServer 를 보면 ScheduledThreadPoolExecutor 를 사용하고 있음
선수 지식
- Tomcat 은 왜 ScheduledThreadPoolExecutor 를 사용하는가?
- NIO Connector 에 대한 이해 필요
- 스트림 vs 채널에 대한 이해 필요
-
Spring Boot 는 Tomcat 을 내장 Servlet Container 로 사용
-
Tomcat 은 Thread Pool 을 통해 다중 요청을 처리
-
요청이 들어오면 Thread Pool 에서 Thread 를 할당
-
스프링과 스프링부트의 차이점 = 내장 Servlet Container 지원 여부
스프링부트와 내장 톰캣
- 위 설정을 통해 Tomcat 의 ThreadPoolExecutor 와 Connector 를 설정할 수 있음
- Core Size 만큼 스레드 생성
- 요청이 들어올 때 마다 Queue 에 담아둠
- Core Size 중 idle 상태의 스레드가 있다면 Queue 에서 작업을 꺼내 스레드에 할당
- 만약 idle 상태의 스레드가 없다면 Queue 에서 대기
- Queue 가 가득 차면 새로 스레드를 생성
- maxThreadSize 에 도달하면 connection-refused 반환
- 작업이 완료되면 스레드는 다시 idle 상태
- Queue 가 비어있고 Core Size 이상의 스레드가 생성되어 있다면 초과된 스레드를 destroy
스레드가 너무 많으면 CPU 의 자원을 두고 경합하게되어 처리속도 저하 및 CPU 자원 활용 비효율 발생
따라서, 적절한 스레드 수로 설정하는 것이 필요함
스레드풀 전략과 적정 스레드 개수로 검색
스레드풀
자바에선 ThreadPoolExecutor 를 통해 스레드풀을 사용
accept-count = 작업 대기열
스프링부트는 Integer.MAX 21억 을 줘서 무한 대기열 전략을 기본값으로 사용
이 상태에서 5개의 요청을 보내면?
5개 모두 처리됨
BIO 에선 3개만 처리된다고 하고
NIO 여서 5개가 다 처리된다고 하는데
사실은 max-connections 가 있어서 되는거자나
그럼 max-connections 는 NIO 때문에 가능한가?