How to Implement Traffic Mirroring in Nginx for Server Replication


12 views

Nginx's mirror module allows you to duplicate incoming requests and send them to additional backend servers without affecting the primary request flow. This is particularly useful for:

  • Testing new server configurations with real production traffic
  • Performance benchmarking
  • Data analysis pipelines
  • Blue-green deployment validation

Here's a fundamental configuration to mirror traffic from Server N to both Servers A and B:

http { upstream primary_backend { server A.example.com; } upstream mirror_backend { server B.example.com; } server { listen 80; location /resource { mirror /mirror; mirror_request_body on; proxy_pass http://primary_backend; } location = /mirror { internal; proxy_pass http://mirror_backend$request_uri; proxy_pass_request_body on; proxy_set_header X-Original-URI $request_uri; } } }

For more advanced cases where you need conditional mirroring or different mirroring rates:

map $http_user_agent $mirror_ua { default 0; "~*bot" 0; "~*Mozilla" 1; } server { # ... other config ... location / { if ($mirror_ua) { mirror /mirror; mirror_request_body on; mirror_rate 0.5; } proxy_pass http://primary_backend; } }

When implementing traffic mirroring, keep these factors in mind:

  • Mirroring doubles the outgoing bandwidth from your Nginx instance
  • Mirrored requests don't wait for responses from the mirrored backend
  • Enable mirror_request_body only when necessary to reduce overhead
  • Consider using mirror_rate to limit mirroring volume

Some problems you might encounter:

# Check for mirror module in your Nginx build nginx -V 2>&1 | grep -o with-http_mirror_module # Common errors: # - "mirror" directive is unknown (module not compiled) # - 502 errors on mirrored backend (check connectivity) # - Missing request bodies (enable mirror_request_body)

In modern web architectures, there are cases where you need to duplicate incoming requests to multiple backend servers simultaneously. Common use cases include:

  • Testing new server deployments without affecting production traffic
  • Data migration between different server environments
  • Load testing with real production traffic patterns
  • Implementing blue-green deployment strategies

Nginx provides the ngx_http_mirror_module (available since version 1.13.4) specifically for this purpose. Unlike simple proxying, mirroring sends requests to additional backend servers without waiting for responses, making it ideal for non-blocking traffic duplication.


server {
    listen 80;
    server_name example.com;

    location /resource {
        mirror /mirror;  # Primary mirror directive
        proxy_pass http://server-a;
        
        # Optional timeout settings
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;
    }

    location = /mirror {
        internal;  # Makes this location inaccessible from outside
        proxy_pass http://server-b$request_uri;
        
        # These headers help track mirrored requests
        proxy_set_header X-Mirrored "true";
        proxy_set_header X-Original-Host $host;
    }
}

For more complex scenarios, consider these enhancements:


# Mirroring with conditional logic
map $http_user_agent $is_mirrorable {
    default 1;
    "~*bot|crawler" 0;  # Don't mirror bot traffic
}

server {
    location /api {
        mirror /mirror if=$is_mirrorable;
        proxy_pass http://primary-backend;
    }
}

# Multiple mirror destinations
location /critical {
    mirror /mirror1;
    mirror /mirror2;
    proxy_pass http://main-server;
}

location = /mirror1 {
    internal;
    proxy_pass http://backup-server-1$request_uri;
}

location = /mirror2 {
    internal;
    proxy_pass http://backup-server-2$request_uri;
}

When implementing traffic mirroring:

  • Subrequests created by mirroring consume additional resources
  • Consider rate limiting for mirror destinations to prevent overload
  • Mirrored requests don't affect the original request's response time
  • Monitor memory usage as each mirrored request creates a copy

The mirror module has some important behavioral characteristics:

  • Mirrored requests proceed independently of the main request
  • Failures in mirrored requests don't affect the original response
  • You can log mirror request outcomes separately:

log_format mirror_log '$remote_addr - $status - $request_time';
location = /mirror {
    internal;
    proxy_pass http://mirror-backend$request_uri;
    access_log /var/log/nginx/mirror_access.log mirror_log;
}

For cases where you need conditional routing rather than pure mirroring:


split_clients $request_id $mirror_backend {
    50% "";
    50% "http://mirror-server";
}

server {
    location / {
        proxy_pass $mirror_backend;
        proxy_pass http://primary-server;
    }
}