Nginx-Tomcat Reverse Proxy 연동
Nginx가 앞단에서 요청을 받고 Tomcat HTTP Connector로 전달하는 reverse proxy 구성과 장애 점검 포인트를 정리한다.
proxy_pass 요청 경로
Client
-> Nginx
-> proxy_pass
-> Tomcat HTTP Connector
Nginx-Tomcat 연동은 Nginx가 외부 요청을 받고 Tomcat의 HTTP Connector로 전달하는 구조다.
연동 방식 요약
Nginx의 proxy_pass는 요청을 뒤쪽 Tomcat으로 전달하고, proxy_set_header는 원래 요청 정보를
Tomcat과 애플리케이션에 전달한다.
기본 구성
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Tomcat은 127.0.0.1:8080에서 내부 요청만 받게 두고, 외부에는 Nginx만 노출하는 방식이 흔하다.
proxy_pass 경로 주의
location /app/ {
proxy_pass http://127.0.0.1:8080/app/;
}
location과 proxy_pass의 끝 슬래시 여부는 backend로 전달되는 URI에 영향을 준다. 404가 나면
먼저 Nginx가 Tomcat에 어떤 URI로 요청을 넘겼는지 access log와 Tomcat access log를 비교한다.
upstream 구성
upstream tomcat_backend {
server 127.0.0.1:8080 max_fails=3 fail_timeout=10s;
server 127.0.0.1:8081 max_fails=3 fail_timeout=10s;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://tomcat_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
upstream은 여러 Tomcat을 하나의 backend 이름으로 묶는다. 세션을 서버 메모리에만 저장하는
애플리케이션이면 sticky session이 필요한지 별도로 판단한다.
HTTPS 앞단 구성
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/tls/example.crt;
ssl_certificate_key /etc/nginx/tls/example.key;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
TLS가 Nginx에서 종료되면 Tomcat은 HTTP 요청을 받는다. 애플리케이션이 HTTPS redirect나 secure cookie를
사용한다면 X-Forwarded-Proto와 애플리케이션 proxy 설정을 같이 확인한다.
timeout과 body 크기
location / {
proxy_pass http://127.0.0.1:8080;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
client_max_body_size 50m;
}
업로드나 긴 요청이 있다면 timeout과 body 크기를 확인한다. Nginx timeout이 먼저 터지면 사용자는 504를 볼 수 있고, Tomcat이나 애플리케이션에서는 요청 처리 중이었을 수 있다.
장애별 확인
| 증상 | 확인 지점 |
|---|---|
| 502 | Tomcat 기동 여부, 포트, proxy_pass 주소, firewall |
| 504 | proxy_read_timeout, Tomcat thread, DB 지연 |
| 404 | location, proxy_pass URI 변환, Tomcat Context |
| 업로드 실패 | client_max_body_size, WAS upload limit |
| 실제 IP 누락 | X-Forwarded-For, Tomcat access log pattern |
| HTTPS loop | X-Forwarded-Proto, 애플리케이션 proxy 설정 |
점검 명령
nginx -t
nginx -T | grep -n "proxy_pass"
curl -I http://127.0.0.1:8080/
curl -I http://example.com/
tail -f /var/log/nginx/error.log
tail -f $CATALINA_BASE/logs/localhost_access_log.*.txt
핵심은 Nginx를 거치지 않은 Tomcat 응답과 Nginx를 거친 응답을 비교하는 것이다.
관련 문서
관련 블로그 기록
- NGINX 부하분산 (HTTP / TCP) — Nginx upstream 구성 사례
- LB·WAF 뒤에서 클라이언트 실제 IP 살리기 — 프록시 헤더와 실제 IP 추적 사례
공식 문서
닫기 전 질문
- Nginx는 Tomcat에 어떤 URI와 Host로 요청을 넘기는가?
- Tomcat은 Nginx 없이 직접 접근했을 때 정상 응답하는가?
- HTTPS 종료 위치와
X-Forwarded-Proto값은 일치하는가? - 502와 504 중 어느 상태 코드이며, 어느 계층의 timeout인가?