recursive_error_pages limited to a chain of 11?

o456092@rtrtr.com nginx-forum at nginx.us
Tue Sep 25 13:41:57 UTC 2012


Hi,

I have configured NGINX as an HTTP Asset locator, where the assets might
found through a series of recursive errors by sequentially a series of
different webservers. The problem that "I think" I have ran into, is that
NGINX's recursive_error_pages is limited to a depth 11 servers, thus 11
errors 404 or 500 errors- is this a fact? Interesting enough I get a 500
internal server error when I hit this 11th member in the chain.

I have tested various scenarios and I always seem to be blocked at the 11th
cascading call with a 500 error - I move different servers around in fear
that one of them (upstream servers) had a problem, but it was not specific
to a server, regardless which asset I was going after
http:<mynginx>/srv<n>/file<n> - once it hit 11 in depth.

Anyone has any ideas of this limitation - or is there something that could
be done?

--------------------------------------------------------------

nginx.conf
========

#user  nobody;
worker_processes  5;

pid        /var/run/nginx.origin.pid;


events {
    worker_connections  10000;
}

http {
    include       /etc/nginx.origin/mime.types;
    default_type  application/octet-stream;

	log_format main '-->$upstream_cache_status<-- | '
	'$remote_addr - $remote_user [$time_local]  "$request" '
	'| Upstream_Address "$upstream_addr" '
	'| upstream_response_time $upstream_response_time '
	'| msec $msec request_time $request_time '
	'| OriginServer $upstream_addr';
	
	log_format cache '***$time_local '
	'-->$upstream_cache_status<-- '
	'Cache-Control: $upstream_http_cache_control '
	'Expires: $upstream_http_expires '
	'"$request" ($status) '
	'"$http_user_agent" ';
		
	access_log  /var/log/nginx/origin.nas.access.log  main;

   sendfile        on;
   keepalive_timeout  65;
   server_tokens off;
	
	add_header Upstream-Host	$upstream_addr;
	add_header Cache-Status		$upstream_cache_status;
	
	client_body_buffer_size  512k;
	proxy_connect_timeout    5;
	proxy_read_timeout       60;
	proxy_send_timeout       5;
	proxy_buffer_size        16k;
	proxy_buffers            4 64k;
	proxy_busy_buffers_size 128k;
	proxy_temp_file_write_size 128k;
	 
	upstream setA {
		server 10.10.30.9:10666;
	}

	upstream setB {
		server 10.10.31.79:10666;
	}
	upstream setC {
		server 10.10.72.109:10666;
	}
	upstream setD {
		server 10.10.72.110:10666;
	}
	upstream setE {
		server 10.10.72.201:10666;
	}
	upstream setF {
		server 10.10.72.127:10666;
	}
	upstream setG {
		server 10.10.72.128:10666;
	}
	upstream setH {
		server 10.10.72.137:10666;
	}
	upstream setI {
		server 10.10.31.238:10666;
	}
	upstream setJ {
		server 10.10.72.134:10666;
	}
	upstream setK {
		server 10.10.72.139:10666;
	}
	upstream setL {
		server 10.10.76.110:10666;
	}
	upstream setM {
		server 10.10.72.141:10666;
	}
	upstream setN {
		server 10.10.72.126:10666;
	}
	upstream setO {
		server 10.10.76.103:10666;
	}
	upstream setY {
		server 10.10.73.90:10666;
		server 10.10.73.91:10666;
	}
	upstream setZ {
		server 10.10.38.88:10666;
		server 10.10.38.89:10666;
	}
	
    server {
        listen       haproxy-local:10777;
        server_name  localhost;
        
       	recursive_error_pages		on; 
		proxy_cache nginx_cache;
		proxy_cache_valid  200 304 12h;
		expires      1d; 
		
		#SetAHandler
		location /
		{
			access_log  /var/log/nginx/origin.handler.a.proxy_access.log  main;
			
			# THIS IS IMPORTANT! Turn this on so the error_page handlers will follow
a chain.
			# This should ONLY be under "location /". If it's under http{} or
server{}, the scope 
			# is too large and we may get an infinite loop.
            #
****************************************************************************************
            # THE STATEMENT ABOVE FAILS TO NOTE THAT:
            # when included under 'location' the chain only allows up to 2
server after the first one
			#
                        error_page 404 502 503 504 500 = @SetBHandler;
			proxy_intercept_errors on;

			#If there is only one server in "server_set_X",
			# make sure it's not the same server this nginx is deployed on.
Otherwise, you'll get a possible infinite loop. 
			#You'll see the error log complain about 'max descriptors'.
			proxy_pass http://setA; 
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			#This is different from how long it takes to READ it. For that, use
proxy_read_timeout
			proxy_connect_timeout 60s; 
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
			
		#	break;
		}

		location @SetBHandler
		{
			access_log  /var/log/nginx/origin.handler.b.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetCHandler;
			proxy_pass http://setB;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		
		location @SetCHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetDHandler;
			proxy_pass http://setC;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		
		location @SetDHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetEHandler;
			proxy_pass http://setD;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
			
		}
		
		location @SetEHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetFHandler;
			proxy_pass http://setE;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
			
		}
		
		location @SetFHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetGHandler;
			proxy_pass http://setF;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
			
		}
		
		location @SetGHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetHHandler;
			proxy_pass http://setG;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		
		location @SetHHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetIHandler;
			proxy_pass http://setH;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		
		location @SetIHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetJHandler;
			proxy_pass http://setI;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		
		location @SetJHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetKHandler;
			proxy_pass http://setJ;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		
		location @SetKHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetLHandler;
			proxy_pass http://setK;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		
		location @SetLHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetMHandler;
			proxy_pass http://setL;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		location @SetMHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetNHandler;
			proxy_pass http://setM;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		location @SetNHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetOHandler;
			proxy_pass http://setN;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		location @SetOHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetYHandler;
			proxy_pass http://setO;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
		location @SetYHandler
		{
			access_log  /var/log/nginx/origin.handler.c.proxy_access.log  main;
			proxy_intercept_errors on;
			
			#If 404, check next server set. If last, it should go to error page.
			error_page 404 502 503 504 500 = @SetZHandler;
			proxy_pass http://setY;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			
		}
				
		location @SetZHandler
		{
			access_log  /var/log/nginx/origin.handler.f.proxy_access.log  main;
			#If 404, check next server set. If last, it should go to error page.
			#error_page 404 502 503 504 /404.html;
			#error_page 404 /404.html;
			proxy_pass http://setZ;
			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_connect_timeout 60s;
			proxy_next_upstream error timeout http_500 http_502 http_503 http_504
http_404;
			#Last proxy, return whatever it gives
			proxy_intercept_errors off;
			
		}
		
		# redirect server error pages to the static page /50x.html
		#
		error_page   500 502 503 504  /50x.html;
		location = /50x.html {
			root   html;
		}
	  
		location = /404.html {
			root		html;
		}
		
		location = /crossdomain.xml {
			access_log  /var/log/nginx/origin.handler.crossdomain.proxy_access.log 
main;
			root		html;
		}
    }

}

Posted at Nginx Forum: http://forum.nginx.org/read.php?21,231038,231038#msg-231038



Подробная информация о списке рассылки nginx-ru