HTTP Keep-Alive는 하나의 TCP 연결을 여러 HTTP 요청에 재사용하는 기능이다.
장점
TCP Handshake 비용 감소
RTT 감소
네트워크 지연 감소
단점
요청 처리가 끝나도 TCP 연결이 유지됨
동시 접속 수가 많을 경우, 유휴 TCP 연결이 커널 자원을 점유
▶ max-connections
max-connections는 Tomcat이 동시에 유지할 수 있는 최대 TCP 연결 수를 의미한다.
Keep-Alive 연결 포함
처리 가능 여부와 무관하게 TCP 연결 자체는 수락
처리할 수 없는 요청이라도 TCP 연결 자체는 수락될 수 있다.
▶ 요청 처리 흐름
요청 하나가 처리되기까지의 전체 흐름은 다음과 같다.
클라이언트 -> TCP 연결 요청
TCP 3-Way Handshake 완료
Accept Queue 대기
Tomcat이 connection을 accept
요청을 처리하기 위한 Runnable 생성
ExecutorService(Thread Pool Queue)에 Runnable 등록
Worker Thread 할당
실제 요청 처리
여기서 Tomcat 기본 작업 큐(Thread Pool Queue)는 Integer.MAX_VALUE로 사실상 무한이다. 따라서, 처리 불가능한 요청도 Runnable 객체로 계속 생성되어 JVM 힙에 쌓인다.
Apache Tomcat 공식 문서 각 들어오는 비동기 요청이 아닌 요청은 해당 요청이 처리되는 동안 스레드를 필요로 한다. 현재 사용 가능한 요청 처리 스레드보다 더 많은 동시 요청이 들어오면, 추가 스레드가 구성된 최대값(maxThreads 속성 값)까지 생성된다. 그럼에도 불구하고 더 많은 동시 요청이 들어오면, Tomcat은 현재 연결 수가 maxConnections에 도달할 때까지 새 연결을 수락한다. 연결은 Connector가 생성한 서버 소켓 내부에 대기열로 저장되며, 스레드가 연결을 처리할 수 있을 때까지 대기한다. maxConnections에 도달하면 운영 체제가 추가 연결을 대기열에 저장한다. 운영 체제에서 제공하는 연결 대기열의 크기는 acceptCount 속성으로 제어할 수 있다. 운영 체제 대기열이 가득 차면 추가 연결 요청이 거부되거나 시간 초과될 수 있다.