设置nginx以将一台服务器上的失败请求代理到另一台服务器

时间:2016-04-27 17:26:32

标签: nginx

我正在开发一个新版本的api,它完全重写了当前的api。首先,新的api不会处理任何请求,但随着时间的推移,将在新的api中实现越来越多的路由(大多数路由使用与旧api中使用的路径相同的路径)。我将nginx设置在与新api服务相同的服务器上(在端口3000上运行的节点),旧的api服务在api.example.com(192.168.1.25)上运行。我想要做的是在新的api服务上指向api.example.com,然后当请求进来时,让nginx首先在新的api服务上尝试请求(127.0.0.1:3000)并且如果该请求返回404 ,然后将请求发送到旧的api服务(192.168.1.25)。

2 个答案:

答案 0 :(得分:2)

我最终使用以下配置使用标头和cookie支持。

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;
    }
  }
}

请注意error_page 417 = @old_backend。这使得nginx从新服务器捕获417响应作为使用旧服务器的触发器。然后我只是向新服务器添加了一个catchall路由以返回417,这样在新服务器上仍可以使用404417 Expectation Failed可能不是此用例最合适的代码,但它看起来足够接近。

此外,这会正确地将http://example.com/some/path代理为https://old.example.com/some/path

答案 1 :(得分:1)

如果您使用' upstream'设置终端,则可以配置proxy_pass以在404上切换try the next upstream

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;
}

然而我不确定的一件事是你是否真的可以切换到"备份"服务器作为proxy_next_upstream的一部分,因为从技术上讲,服务器是健康的。