본문으로 건너뛰기
Advertisement

Tomcat HTTP 커넥터 설정

Tomcat의 HTTP 커넥터는 클라이언트 요청을 수신하는 네트워크 입구입니다. maxThreads, acceptCount, connectionTimeout 등의 파라미터를 올바르게 튜닝하면 처리량과 응답성을 크게 개선할 수 있습니다.


HTTP 커넥터 기본 구조

<!-- server.xml -->
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"/>

protocol 속성 값에 따라 커넥터 구현체가 결정됩니다.

protocol 값구현체특징
HTTP/1.1NIO (자동 선택)기본값, 논블로킹 I/O
org.apache.coyote.http11.Http11NioProtocolNIO명시적 NIO
org.apache.coyote.http11.Http11Nio2ProtocolNIO2비동기 I/O
org.apache.coyote.http11.Http11AprProtocolAPR/Native네이티브 라이브러리 필요

핵심 파라미터

스레드 풀 설정

<Connector port="8080" protocol="HTTP/1.1"
maxThreads="200"
minSpareThreads="10"
maxSpareThreads="75"
acceptCount="100"
connectionTimeout="20000"/>
파라미터설명기본값권장값
maxThreads최대 동시 처리 스레드 수200CPU 코어 × 50~100
minSpareThreads항상 유지할 최소 대기 스레드1010~25
maxSpareThreads최대 유휴 스레드 수75maxThreads × 0.3
acceptCount모든 스레드가 바쁠 때 대기 큐 크기100maxThreads × 0.5

동작 흐름:

요청 도착

[사용 가능한 스레드 있음?]
↓ Yes → 즉시 처리
↓ No → acceptCount 큐에 대기
↓ 큐도 꽉 참 → Connection Refused

타임아웃 설정

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
keepAliveTimeout="15000"
maxKeepAliveRequests="100"/>
파라미터설명기본값
connectionTimeout첫 요청 라인 수신 대기 시간(ms)20000 (20초)
keepAliveTimeoutKeep-Alive 유지 시간(ms)connectionTimeout
maxKeepAliveRequestsKeep-Alive 연결당 최대 요청 수100

프로덕션 팁: Nginx/Apache가 앞단에 있다면 keepAliveTimeout을 충분히 길게 설정합니다 (프록시 keepalive 시간과 동기화).

연결 및 요청 크기 제한

<Connector port="8080" protocol="HTTP/1.1"
maxConnections="10000"
maxHttpHeaderSize="8192"
maxPostSize="2097152"
maxParameterCount="1000"/>
파라미터설명기본값
maxConnectionsNIO: 최대 동시 연결 수10000
maxHttpHeaderSize요청/응답 헤더 최대 크기(bytes)8192 (8KB)
maxPostSizePOST 본문 최대 크기(bytes)2097152 (2MB)
maxParameterCount최대 파라미터 수10000 (Tomcat 10.1)

HTTPS 커넥터 설정

방법 1: Java Keystore(JKS) 사용

# 자체 서명 인증서 생성 (테스트용)
keytool -genkey -alias tomcat \
-keyalg RSA -keysize 2048 \
-keystore /opt/tomcat/conf/keystore.jks \
-validity 365 \
-storepass changeit \
-keypass changeit \
-dname "CN=localhost, OU=Dev, O=MyCompany, L=Seoul, ST=Seoul, C=KR"
<!-- HTTPS 커넥터 (JKS) -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/keystore.jks"
certificateKeystorePassword="changeit"
type="RSA"/>
</SSLHostConfig>
</Connector>

방법 2: PEM 인증서 직접 사용 (Let's Encrypt 등)

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateFile="/etc/letsencrypt/live/example.com/cert.pem"
certificateKeyFile="/etc/letsencrypt/live/example.com/privkey.pem"
certificateChainFile="/etc/letsencrypt/live/example.com/chain.pem"
type="RSA"/>
</SSLHostConfig>
</Connector>

프로덕션 권장: Tomcat에서 직접 SSL을 처리하기보다 Nginx/Apache에서 SSL Termination 후 HTTP로 Tomcat에 전달하는 패턴을 사용합니다. 성능과 인증서 관리가 훨씬 편리합니다.


압축(Gzip) 설정

<Connector port="8080" protocol="HTTP/1.1"
compression="on"
compressionMinSize="2048"
compressibleMimeType="text/html,text/xml,text/plain,text/css,
application/json,application/javascript"/>
파라미터설명기본값
compressionon/off/forceoff
compressionMinSize압축 적용 최소 응답 크기(bytes)2048
compressibleMimeType압축 대상 MIME 타입

스레드 풀 공유 (Executor)

여러 커넥터가 하나의 스레드 풀을 공유할 때 Executor를 사용합니다.

<!-- 공유 스레드 풀 정의 -->
<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="400"
minSpareThreads="20"
maxQueueSize="100"
prestartminSpareThreads="true"/>

<!-- 커넥터에서 Executor 참조 -->
<Connector port="8080" protocol="HTTP/1.1"
executor="tomcatThreadPool"
connectionTimeout="20000"/>

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
executor="tomcatThreadPool"
SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateFile="conf/cert.pem"
certificateKeyFile="conf/key.pem"/>
</SSLHostConfig>
</Connector>

X-Forwarded-For 설정 (리버스 프록시 환경)

Nginx나 Apache 앞에서 프록시될 때 실제 클라이언트 IP를 Tomcat에 전달합니다.

<!-- RemoteIpValve: X-Forwarded-For 헤더를 실제 IP로 처리 -->
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="x-forwarded-for"
proxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto"
internalProxies="127\.0\.0\.1|10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+"/>

이 Valve를 설정하면 request.getRemoteAddr()가 실제 클라이언트 IP를 반환하고, request.isSecure()가 HTTPS 여부를 올바르게 반환합니다.


커넥터 성능 튜닝 — 실전 체크리스트

소규모 서버 (2 CPU, 4GB RAM)

<Connector port="8080" protocol="HTTP/1.1"
maxThreads="100"
minSpareThreads="10"
acceptCount="50"
connectionTimeout="10000"
keepAliveTimeout="10000"
maxKeepAliveRequests="50"/>

중규모 서버 (48 CPU, 816GB RAM)

<Connector port="8080" protocol="HTTP/1.1"
maxThreads="300"
minSpareThreads="25"
acceptCount="150"
connectionTimeout="20000"
keepAliveTimeout="15000"
maxKeepAliveRequests="100"
maxConnections="10000"/>

대규모 서버 (16+ CPU, 32GB+ RAM)

<Executor name="tomcatThreadPool"
maxThreads="800"
minSpareThreads="50"
maxQueueSize="200"/>

<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
executor="tomcatThreadPool"
connectionTimeout="30000"
maxConnections="20000"/>

커넥터 상태 모니터링

JMX를 통해 커넥터 상태를 실시간으로 확인할 수 있습니다.

# setenv.sh에 JMX 활성화 추가
export CATALINA_OPTS="$CATALINA_OPTS \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9090 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false"

또는 tomcat-manager 웹 앱을 통해 현재 활성 스레드 수, 처리된 요청 수 등을 확인할 수 있습니다.


Summary

설정파라미터권장 기준
최대 스레드maxThreadsCPU 코어 수 × 50 (IO 바운드)
대기 큐acceptCountmaxThreads × 0.5
연결 타임아웃connectionTimeout10000~20000ms
스레드 공유Executor커넥터 2개 이상일 때 사용
실제 IP 전달RemoteIpValve리버스 프록시 필수
압축compression="on"JSON/HTML 응답에 권장
Advertisement