Setting up nginx to proxy failed requests on one server to another

懵懂的女人 提交于 2021-02-19 03:39:06

问题


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 404s 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!