问题
I am working on a new version of an api that is a complete rewrite of the current api. To start, the new api will not handle any requests, but over time, more and more routes will be implemented in the new api (most of them using the same path that they use in the old api). I have nginx set up on the same server as the new api service (node running on port 3000) and the old api service is running at api.example.com (192.168.1.25). What I want to do is point api.example.com at the new api service, then when a request comes in, have nginx first try the request on the new api service (127.0.0.1:3000) and if that request returns a 404, then send the request to the old api service (192.168.1.25).
回答1:
I ended up getting this to work with header and cookie support using the following config.
http {
upstream new_api_backend {
server 127.0.0.1:3000;
}
upstream old_api_backend {
server old.example.com:443;
}
server {
listen 80;
return 301 https://$http_host$request_uri;
}
server {
proxy_http_version 1.1;
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/my_cert.crt;
ssl_certificate_key /etc/nginx/ssl/my_cert.key;
location / {
proxy_intercept_errors on;
error_page 417 = @old_backend;
proxy_pass http://new_api_backend;
}
location @old_backend {
proxy_set_header Host old.example.com;
proxy_redirect https://old.example.com/ https://$http_host/;
proxy_cookie_domain old.example.com $http_host;
proxy_pass https://old_api_backend;
}
}
}
Note the error_page 417 = @old_backend
. This makes nginx catch a 417
response from the new server as the trigger to use the old server. Then I just added a catchall route to the new server to return 417
, that way 404
s can still be used when appropriate on the new server. 417 Expectation Failed
may not be the most appropriate code for this use case, but it looked close enough.
Also, this will correctly proxy http://example.com/some/path
to https://old.example.com/some/path
.
回答2:
If you set up your endpoint using an 'upstream', then you can configure the proxy_pass to switch try the next upstream on 404.
upstream api {
# new
server localhost:3000;
# old
server 129.168.1.25:3000 backup;
}
location / {
proxy_pass http://api;
proxy_next_upstream http_404 non_idempotent;
}
One thing however that I am not certain about is whether you can actually switch to a "backup" server as part of proxy_next_upstream, since technically the server is healthy.
来源:https://stackoverflow.com/questions/36896821/setting-up-nginx-to-proxy-failed-requests-on-one-server-to-another