1. 개요
Tomcat의 HTTP Thread Pool과 AJP Thread Pool에 대해 설명한다.
2. HTTP Thread Pool
- Tomcat 버전 : 7.0.70 (2016-06-20 Release)
- Tomcat 설정 : 기본 설정
아래는 Tomcat을 기동하고 아무 행위를 하지 않았을 때 Thread Pool의 수치가 어떻게 변화하는지 확인하는 실험이다.
시간 | 내용 | Thread 수 |
10:11:29 | 기동 시작 | |
10:11:29 | Initializing ProtocolHandler ["http-bio-8080"] | |
10:11:30 | Initializing ProtocolHandler ["ajp-bio-8009"] | |
10:11:31 | Dump #0 - HTTP Thread Pool (http-bio-8080-exec-) | 0개 |
10:11:34 | Server startup in 4350 ms | |
10:11:35 | Dump #1 - HTTP Thread Pool (http-bio-8080-exec-) | 0개 |
10:11:38 | Dump #2 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:11:41 | Dump #3 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:11:45 | Dump #4 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:11:48 | Dump #5 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:11:52 | Dump #6 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:11:55 | Dump #7 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:11:58 | Dump #8 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:12:02 | Dump #9 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:12:05 | Dump #10 - HTTP Thread Pool (http-bio-8080-exec-) | 3개 |
10:12:09 | Dump #11 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:12 | Dump #12 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:15 | Dump #13 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:19 | Dump #14 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:22 | Dump #15 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:26 | Dump #16 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:29 | Dump #17 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:33 | Dump #18 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:36 | Dump #19 - HTTP Thread Pool (http-bio-8080-exec-) | 6개 |
10:12:39 | Dump #20 - HTTP Thread Pool (http-bio-8080-exec-) | 9개 |
10:12:43 | Dump #21 - HTTP Thread Pool (http-bio-8080-exec-) | 9개 |
10:12:46 | Dump #22 - HTTP Thread Pool (http-bio-8080-exec-) | 9개 |
10:12:50 | Dump #23 - HTTP Thread Pool (http-bio-8080-exec-) | 9개 |
10:12:53 | Dump #24 - HTTP Thread Pool (http-bio-8080-exec-) | 9개 |
10:12:57 | Dump #25 - HTTP Thread Pool (http-bio-8080-exec-) | 9개 |
10:13:00 | Dump #26 - HTTP Thread Pool (http-bio-8080-exec-) | 9개 |
10:13:03 | Dump #27 - HTTP Thread Pool (http-bio-8080-exec-) | 9개 |
10:13:07 | Dump #28 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
10:13:10 | Dump #29 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
10:13:14 | Dump #30 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
10:13:17 | Dump #31 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
10:13:20 | Dump #32 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
10:13:24 | Dump #33 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
10:13:27 | Dump #34 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
10:13:31 | Dump #35 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
10:13:34 | Dump #36 - HTTP Thread Pool (http-bio-8080-exec-) | 10개 |
3. AJP Thread Pool
3-1. Tomcat 기동 후 Startup 완료, 아직 요청 없는 상태
<http-apr-8180-exec-일련번호>와 같은 Worker Thread가 하나도 존재하지 않는다.
3-2. 최초 요청 유입
요청 하나 당 <http-apr-8180-exec-1>과 같은 Worker Thread가 1개 생성된다.
3-3. 동시 Thread 처리
동시 요청량에 따라 <http-apr-8180-exec-일련번호> Thread들이 생성된다.
3-4. 모든 요청 종료 후 Thread Idle 상태 유지 시
각 Thread 별로 Idle 60초 후 Thread drop되며, 총 Idle Thread가 minSpareThreads(기본 10) 값에 도달할 경우 더이상 Thread drop되지 않는다.
3-5.
중요한 것은 60초. http Connector 설정 중 connectionTimeout이나 keepAliveTimeout이 20000(20초)이든 90000(90초)이든 요청 처리 후 무조건 Idle 60초 후에 Thread drop된다. AbstractEndpoint 클래스를 확인해보자.
public void createExecutor() { internalExecutor = true; TaskQueue taskqueue = new TaskQueue(); TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority()); executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf); taskqueue.setParent( (ThreadPoolExecutor) executor); }
그리고 ThreadPoolExecutor의 생성자이다.
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, new RejectHandler()); }
위와 같이 keepAliveTime이 60초로 고정되어 있음을 확인할 수 있다.
4. 요약
- 기동 후 실 요청이 들어오지 않으면 AJP Worker Thread는 0개이다. (단, AsyncTimeout, Acceptor, Poller Thread 등 제외)
- 별도로 keepAliveTimeout를 설정하지 않으면 connectionTimeout과 동일한 값으로 설정된다고 가이드되어 있으나, 위와 같이 확인한 결과 60초로 강제 설정되고 있다. (단, Executor가 아닌 개별 Connector 사용 시)
- keepAliveTimeout을 90000(ms, =90초) 등 명시적으로 설정하더라도 역시 60초 keepAliveTImeout이 적용된다.