공공부하자개발 · 영어 학습 노트
리눅스
웹 서버Tomcat · Nginx 설치와 설정0/8 완료
  • 01Tomcat 설치
  • 02Tomcat server.xml 설정
  • 03Tomcat 인스턴스와 JVM 옵션
  • 04Tomcat 보안과 운영 점검
  • 05nginx 설치
  • 06nginx 리버스 프록시
  • 07nginx HTTPS
  • 08nginx 로드밸런싱과 운영
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 웹 서버 › 02 / 8

Tomcat server.xml 설정

섹션 7진행 0 / 8
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

2. 핵심 원리

2.1 server.xml 요소 계층

server.xml 은 아래 계층으로 중첩됩니다. 괄호 없이 텍스트로 정리하면 이렇습니다.

text
Server (port=종료 포트)
  GlobalNamingResources
  Service
    Connector (HTTP, AJP 등 포트별로 여러 개)
    Engine (defaultHost 지정)
      Host (name=가상 호스트, appBase=배포 폴더)
        Valve (AccessLogValve, RemoteIpValve 등)
        Context (앱 하나, 보통 별도 context.xml 로 분리)

Server 아래 Service 는 보통 하나(Catalina)이고, 그 안에 Connector 여러 개와 Engine 하나가 들어갑니다. Host 는 도메인별 가상 호스트이고 그 안의 Valve 가 요청을 가로채 로그를 남기거나 헤더를 고칩니다.

2.2 Server 요소와 종료 포트

Server 요소의 port 속성이 바로 종료(shutdown) 포트입니다. 이 포트로 SHUTDOWN 문자열을 보내면 Tomcat 이 완전 종료됩니다. 기본값 8005 는 다른 인스턴스와 겹치기 쉬워 설치마다 바꿔야 합니다.

속성 기본값 의미
port 8005 종료 명령을 받는 포트
shutdown SHUTDOWN 종료를 트리거하는 문자열

종료 포트를 외부에 열어 두면 문자열만 알면 누구나 Tomcat 을 내릴 수 있습니다. 04 레슨에서 이 포트를 -1 로 막는 방법을 다룹니다.

2.3 Connector 종류와 포트 충돌

Connector 는 포트마다 하나씩 선언하며 프로토콜(HTTP/1.1, AJP/1.3)을 속성으로 지정합니다. 기본 8080(HTTP), 8009(AJP), 8443(HTTPS, 주석 처리) 세 개가 기본 제공됩니다. 같은 서버에 다른 앱이 8080 을 쓰면 바로 기동 실패로 이어집니다.

인스턴스를 여러 개 두는 경우(03 레슨) 포트가 인스턴스마다 겹치지 않아야 합니다. 포트를 정할 때는 종료 포트, HTTP 포트, 리다이렉트 포트를 함께 관리 대장에 적어 두는 편이 안전합니다.

2.4 HTTP Connector 스레드와 대기열

maxThreads 는 동시에 요청을 처리하는 최대 스레드 수이고, acceptCount 는 스레드가 모두 찼을 때 대기시킬 수 있는 연결 수입니다. 두 값을 넘는 요청은 즉시 거절되거나 타임아웃됩니다.

속성 기본값 의미
maxThreads 200 동시 처리 최대 스레드 수
acceptCount 100 대기열 최대 연결 수
connectionTimeout 60000 연결 유지 제한시간(ms)

값을 무작정 키우면 스레드 경쟁과 메모리 사용만 늘어납니다. 예상 동시접속과 WAS 뒤 DB 커넥션 풀 크기를 함께 보고 정합니다.

2.5 인코딩과 업로드 한도

URIEncoding 은 URL 경로·쿼리를 디코딩할 문자셋이고, 지정하지 않으면 버전에 따라 다를 수 있어 명시하는 편이 안전합니다. maxPostSize 는 폼 데이터 본문 크기, maxSwallowSize 는 오류 응답을 보내기 전 남은 요청 본문을 읽어 버리는 한도입니다.

속성 기본값 의미
URIEncoding 버전마다 다름 URL 디코딩 문자셋
maxPostSize 2097152 POST 본문 최대 크기(byte)
maxSwallowSize 2097152 오류 시 요청 흡수 한도(byte)
compression off gzip 압축 여부

URIEncoding="UTF-8" 을 빠뜨리면 한글 파라미터가 깨지는 문제가 자주 나옵니다. 업로드 앱은 maxPostSize 를 파일 크기 정책에 맞춰 올려야 합니다.

2.6 AJP 커넥터를 지우는 이유

AJP(Apache JServ Protocol)는 아파치 웹서버 연동용 프로토콜입니다. 2020년 CVE-2020-1938(일명 Ghostcat)로 AJP 포트가 노출되면 파일을 읽히는 취약점이 알려졌습니다. nginx 는 AJP 가 아닌 HTTP 로 프록시하므로 이 커넥터는 대부분 필요 없습니다.

쓰지 않는 포트는 지우는 편이 가장 안전합니다. 꼭 필요하면 secretRequired="true" 와 address="127.0.0.1" 로 로컬 전용으로 좁혀야 합니다.

2.7 Engine 과 Host, defaultHost

Engine 은 들어온 요청을 어느 Host 로 보낼지 결정하는 상위 컨테이너입니다. defaultHost 는 요청의 Host 헤더가 어떤 Host 이름과도 안 맞을 때 쓸 기본값입니다. 보통 Host 는 localhost 하나만 두고 도메인 여러 개는 Alias 로 묶습니다.

2.8 Host appBase 분리와 자동 배포

appBase 는 war·앱 폴더를 두는 위치이고, 기본값 webapps 는 Tomcat 설치 폴더 기준 상대경로입니다. 버전 업그레이드 시 폴더가 바뀌는 01 레슨 구조와 맞추려면 $BASE/webapps 같은 절대경로로 분리해야 앱이 그대로 남습니다.

속성 의미
appBase war·앱 폴더 위치
autoDeploy 실행 중 새 war 자동 배포
unpackWARs war 를 풀어서 서비스

운영에서는 autoDeploy 를 켜 두면 실수로 넣은 war 가 바로 배포될 수 있어, 배포 절차(리눅스 운영 05 참조)로 통제하는 편이 안전합니다.

2.9 AccessLogValve 위치와 pattern

AccessLogValve 는 Host 안에 넣는 Valve 로, 요청마다 한 줄씩 로그를 남깁니다. directory 는 로그 폴더, pattern 은 로그 형식이며 %D 를 넣으면 응답 처리 시간(ms)이 같이 찍힙니다.

pattern 기호 의미
%h 접속 클라이언트 주소
%t 요청 시각
%r 요청 줄(메서드·경로)
%s 응답 상태 코드
%b 응답 바이트 수
%D 응답 처리 시간(ms)

%D 로 느린 요청을 로그만 보고 걸러낼 수 있어 장애 조사 첫 단계로 자주 씁니다.

2.10 RemoteIpValve 와 실제 IP

nginx 뒤에 Tomcat 을 두면 접근 로그의 %h 가 전부 nginx 서버 주소(127.0.0.1)로 찍힙니다. RemoteIpValve 는 X-Forwarded-For, X-Forwarded-Proto 헤더를 읽어 실제 클라이언트 IP 와 원래 프로토콜(http/https)을 복원합니다.

속성 의미
remoteIpHeader 실제 클라이언트 IP 헤더 이름
protocolHeader 원래 프로토콜 헤더 이름
internalProxies 신뢰할 프록시 IP 대역(정규식)

internalProxies 를 nginx 가 있는 서버 대역으로만 좁혀야 합니다. 너무 넓게 잡으면 외부 요청자가 헤더를 위조해 IP 를 속일 수 있습니다.

2.11 변경은 재시작으로 반영

server.xml 은 핫 리로드 대상이 아닙니다. Connector, Host, Valve 를 고쳤으면 Tomcat 을 재시작해야 반영됩니다. war 배포·nginx 전환 같은 무중단 절차는 리눅스 운영 05 를 참조합니다.

2.12 변경 후 XML 검증 습관

sed 로 태그 하나만 잘못 지워도 Tomcat 은 파싱 오류로 기동을 거부합니다. python3 -c 'import xml.dom.minidom as m; m.parse(f)' 로 문법만 빠르게 확인하고, 실제 서버에서는 catalina.sh configtest 계열 점검이나 시험 기동으로 한 번 더 확인합니다.

핵심 원리
  • 2.1 server.xml 요소 계층
  • 2.2 Server 요소와 종료 포트
  • 2.3 Connector 종류와 포트 충돌
  • 2.4 HTTP Connector 스레드와 대기열
  • 2.5 인코딩과 업로드 한도
  • 2.6 AJP 커넥터를 지우는 이유
  • 2.7 Engine 과 Host, defaultHost
  • 2.8 Host appBase 분리와 자동 배포
  • 2.9 AccessLogValve 위치와 pattern
  • 2.10 RemoteIpValve 와 실제 IP
  • 2.11 변경은 재시작으로 반영
  • 2.12 변경 후 XML 검증 습관
이전 섹션1 왜 배우는가2 / 7다음 섹션3 코드 예제