Upstream and Reverse Proxy Basics
Nginx's reverse proxy feature is the core mechanism for forwarding client requests to backend servers like Tomcat. Correctly configuring proxy_pass, header forwarding, buffering, and timeouts is essential for a stable proxy setup.
Reverse Proxy Concept
A reverse proxy sits between clients and backend servers, relaying requests. Clients connect only to Nginx and are unaware of the backend servers (Tomcat, etc.).
[Client]
│ GET /api/products HTTP/1.1
│ Host: example.com
▼
[Nginx: Reverse Proxy]
│ GET /api/products HTTP/1.1
│ Host: example.com
│ X-Real-IP: client IP
▼
[Tomcat: Backend Server]
│
└─ Response → Nginx → Client
Basic proxy_pass Configuration
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://127.0.0.1:8080;
}
}
URI Handling Difference in proxy_pass
# Case 1: No URI — location path forwarded as-is
location /api/ {
proxy_pass http://127.0.0.1:8080;
}
# GET /api/users → Backend: GET /api/users
# Case 2: URI with trailing slash — location path replaced by /
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}
# GET /api/users → Backend: GET /users
# Case 3: URI with path — location path replaced by that path
location /api/ {
proxy_pass http://127.0.0.1:8080/app/;
}
# GET /api/users → Backend: GET /app/users
Header Forwarding
Nginx strips some headers by default when forwarding requests. Add headers so the backend knows the real client IP, original domain, etc.
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
upstream Block — Backend Server Group
Use an upstream block to manage multiple backend servers or reference them by name.
http {
upstream tomcat_backend {
server 127.0.0.1:8080;
}
server {
location /api/ {
proxy_pass http://tomcat_backend;
}
}
}
Shared proxy params file
# /etc/nginx/conf.d/proxy-params.conf
proxy_http_version 1.1;
proxy_set_header Connection "";
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;
# Use with include:
location / {
proxy_pass http://tomcat_backend;
include /etc/nginx/conf.d/proxy-params.conf;
}
Buffer Settings
Nginx buffers backend responses before delivering to clients. Incorrect buffer settings waste memory or degrade performance.
location / {
proxy_pass http://tomcat_backend;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
proxy_max_temp_file_size 1024m;
}
Streaming Responses (SSE, WebSocket)
Disable buffering for streaming or real-time responses:
# Server-Sent Events (SSE)
location /api/stream {
proxy_pass http://tomcat_backend;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
add_header X-Accel-Buffering no;
}
# WebSocket
location /ws/ {
proxy_pass http://tomcat_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
Timeout Settings
location / {
proxy_pass http://tomcat_backend;
proxy_connect_timeout 10s; # Max wait for TCP connection to backend
proxy_send_timeout 60s; # Max wait for completing request transmission
proxy_read_timeout 60s; # Max wait for reading backend response
}
HTTP Version and Keep-Alive
Keeping HTTP/1.1 Keep-Alive between Nginx and backend reuses TCP connections, improving performance.
upstream tomcat_backend {
server 127.0.0.1:8080;
keepalive 32; # Keep up to 32 idle Keep-Alive connections
}
location /api/ {
proxy_pass http://tomcat_backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # Remove Connection: close header
}
Error Handling and Backup Servers
upstream tomcat_backend {
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 backup; # Used when main server is down
}
server {
location / {
proxy_pass http://tomcat_backend;
proxy_next_upstream error timeout http_502 http_503;
proxy_intercept_errors on;
error_page 502 503 504 /maintenance.html;
}
}
Summary
| Setting | Directive | Key Point |
|---|---|---|
| Request forwarding | proxy_pass | URI inclusion changes path handling |
| Header forwarding | proxy_set_header | Host, X-Real-IP, X-Forwarded-For required |
| Buffering | proxy_buffering | Off for streaming, on for normal responses |
| Timeout | proxy_read_timeout | Adjust for slow APIs |
| Keep-Alive | keepalive + HTTP/1.1 | TCP reuse for performance gain |