I don't believe you can pass a redirect using a 503 as it's not intended for redirection.
You'll either need to host that specific file in a safe location so it's unaffected by whatever maintenance system is in effect, or use a proxy_pass so that nginx fetches the page from amazon and then passes it on to the client.
Something along these lines might do the trick. Haven't touched nginx in a while, but this might give you an idea of what I'm suggesting:
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.html break;
proxy_pass http://mysite.s3-website-us-east-1.amazonaws.com;
}
Edit: On the page referenced about Google's recommendation for a 503, someone commented a fantastic idea for how to redirect with a 503. He mentioned it for Apache, but the concept is the same with nginx:
Hi!
This might help. On Apache Servers, it's usually not possible to redirect a user with any other HTTP Status Code than of the 3xx class.
Users that visit a site under maintenance deserve to get a useful information page.
Do this with a 302 redirect first that leads to a 503 page that outputs the 503 header (i.e. via PHP or Perl). This will work fine with Google since Google will assign all target page properties to the source page when they encounter a 302 - including the header response. I've tested this on Virtual Hosts and it works as desired. If you can, choose a time with few requests for the service actions.
Regards, Thomas
Sending Last-Modified
headers in your app replies is a start but it seems you don't handle If-Modified-Since
properly on incoming requests because your app should reply 304 Not Modified
and not 200 OK
. Changing the directive on nginx only impact requests served directly by nginx i.e. static ressources unless you configure it as a reverse proxy cache. In this case, you may serve stale replies regarding this header value since content will be cached for a period of time without hitting your app. Turning <X>_cache_revalidate
on will use the If-Modified-Since
header to revalidate cache content between nginx's cache and your app once it has expired (where <X>
= proxy / fastcgi / scgi / uwsgi)
Best Answer
From a (fairly cursory) reading of
ngx_http_upstream_get_peer
it seems nginx will pick a weight=0 server if there is nothing else to pick at all.Specifically see https://github.com/nginx/nginx/blob/3fae83a91c6e5cda012adf6ee2783273e747f613/src/http/ngx_http_upstream_round_robin.c#L558