Practical Nginx Performance Tuning for Backend Optimization

Practical Nginx Performance Tuning for Backend Optimization

Problem Description
Nginx, as a core component of modern backend architecture, directly impacts the overall system's throughput and response time. The interviewer aims to understand your systematic tuning strategies to maximize Nginx's efficiency under high-concurrency scenarios.

Key Knowledge Points

  1. Nginx Process Model and Event Handling Mechanism
  2. Tuning Key Performance Parameters
  3. Static Resource Optimization Strategies
  4. Load Balancing and Health Check Configuration

Detailed Analysis

I. Understanding Nginx's Basic Architecture

Nginx employs the Master-Worker multi-process model:

  • Master Process: Manages Worker processes and does not handle specific requests.
  • Worker Process: The actual process handling network requests (default count = number of CPU cores).
Startup Process:
1. Master process reads and validates the configuration file syntax.
2. Master process binds to the listening port (80/443).
3. Master process forks a specified number of Worker processes.
4. Worker processes handle client requests via epoll (Linux).

Key Advantage: Worker processes are independent of each other; a single process crash does not affect the overall service.

II. Core Parameter Tuning

1. Worker Process Optimization

# Set the number of Worker processes (Recommended = CPU core count)
worker_processes auto;

# Set CPU affinity for Worker processes (reduce context switching)
worker_cpu_affinity auto;

# Maximum connections per Worker process (limited by system file descriptors)
worker_connections 10240;

Calculate maximum concurrent connections = worker_processes × worker_connections

2. Event Model Optimization

events {
    # Use epoll (efficient I/O model for Linux)
    use epoll;
    
    # Allow accepting multiple connections simultaneously
    multi_accept on;
    
    # Maximum connections per Worker process
    worker_connections 10240;
}

3. Connection Timeout Optimization

http {
    # Client connection timeouts (prevent slow clients from occupying connections)
    client_header_timeout 15s;
    client_body_timeout 15s;
    
    # Keepalive connection timeouts (reduce TCP handshake overhead)
    keepalive_timeout 30s;
    keepalive_requests 100;
    
    # Send timeout (prevent network failures)
    send_timeout 15s;
    
    # Enable zero-copy transmission with sendfile
    sendfile on;
    
    # Enable direct I/O for large file transfers
    directio 4m;
}

IV. Practical Static Resource Optimization

1. Gzip Compression Configuration

gzip on;
gzip_min_length 1k;        # Compress only files larger than 1KB
gzip_comp_level 6;         # Compression level (1-9)
gzip_types text/plain text/javascript application/javascript application/json;
gzip_vary on;              # Add Vary header for cache support

2. Cache Header Optimization

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 7d;                    # Cache for 7 days
    add_header Cache-Control "public, immutable";
    
    # Try next location if file doesn't exist
    try_files $uri $uri/ =404;
}

3. Static File Service Optimization

location /static/ {
    # Enable zero-copy to reduce kernel-to-user space copying
    sendfile on;
    
    # Large file transfer optimization (use direct I/O for files >4MB)
    directio 4m;
    
    # Enable asynchronous I/O
    aio on;
    
    # Output buffer optimization
    output_buffers 4 32k;
}

V. Upstream Service Tuning

1. Load Balancing Configuration

upstream backend {
    # Least connections algorithm
    least_conn;
    
    server 192.168.1.10:8080 weight=3 max_fails=2 fail_timeout=30s;
    server 192.168.1.11:8080 weight=2 max_fails=2 fail_timeout=30s;
    
    # Keepalive connection pool size
    keepalive 32;
}

server {
    location /api/ {
        proxy_pass http://backend;
        
        # Upstream timeout settings
        proxy_connect_timeout 3s;
        proxy_send_timeout 10s;
        proxy_read_timeout 10s;
        
        # Enable connection reuse
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

2. Health Check Configuration

upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080 backup;  # Backup server
    
    # Active health checks
    check interval=3000 rise=2 fall=3 timeout=1000;
}

# Health check status page
location /nginx_status {
    check_status;
    access_log off;
    allow 192.168.1.0/24;
    deny all;
}

VI. System-Level Optimization Coordination

1. System File Descriptor Adjustment

# View current limits
ulimit -n

# Permanent modification (/etc/security/limits.conf)
* soft nofile 65535
* hard nofile 65535

# System-level modification (/etc/sysctl.conf)
fs.file-max = 100000

2. Network Stack Optimization

# Increase TCP buffer sizes
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 16384 16777216

# Enable TCP Fast Open
net.ipv4.tcp_fastopen = 3

Performance Verification Methods

  1. Use ab or wrk for stress testing.
  2. Monitor Nginx status: nginx -t and nginx -s reload.
  3. Real-time monitoring: nginx -V to view module support.

Through the systematic tuning above, Nginx can easily handle tens of thousands of concurrent connections, significantly improving the overall performance of the backend system.