我正在使用 NGINX 作为负载平衡器来运行我的网站的多个实例。我正在研究条件路由,以根据传入的 HTTP 标头将用户发送到特定服务器。最终目标是拥有一个使用 ip_hashing 进行负载平衡的 X 服务器上游,以发送给具有 beta 测试者标志的用户,以及一个具有 Y 服务器的稳定上游,供尚未选择加入的用户使用。
我的问题在于从一个组到另一个组的故障转移——具体来说,如果没有可用的测试服务器,测试用户应该重新路由到稳定的服务器。不幸的是,备份和权重指令在 ip_hashed 上游中都不起作用,尽管当前的 NGINX 文档似乎表明它们应该起作用。
作为一种解决方法,我尝试为 502 和 504 设置一个自定义错误位置,以便将 proxy_pass 传递到我的稳定上游。但是,当我测试我的配置时,我发现页面是空白的,带有 504 标头且没有重定向。我目前的解决方案基于此线程:
worker_processes 2;
events {
worker_connections 1024;
}
http {
upstream dataserver_stable {
ip_hash;
server localhost:8081;
}
upstream dataserver_beta {
ip_hash;
server localhost:8082 fail_timeout=1m;
#server localhost:8081 backup; # backup and weight aren't working with the ip_hash directive
}
geo $beta_user {
default stable;
10.17.12.246 beta;
}
map $beta_user $upstream {
stable dataserver_stable;
beta dataserver_beta;
}
server {
listen 81;
server_name localhost;
set_real_ip_from 27.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location / {
error_page 502 504 @fallback;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $realip_remote_addr;
proxy_pass http://$upstream;
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
}
location @fallback {
proxy_pass http://dataserver_stable;
}
}
}
任何意见,将不胜感激。
答案1
虽然这篇文章已有 6 年历史,但我还是遇到了对 nginx 的“哈希一致”负载平衡功能同样的需求。基于这个 nginx 示例配置,我相信您缺少的是指令,proxy_intercept_errors on;
以便 nginx 消耗错误而不是将其传递给客户端。
完整来说,您的配置将如下所示:
worker_processes 2;
events {
worker_connections 1024;
}
http {
upstream dataserver_stable {
ip_hash;
server localhost:8081;
}
upstream dataserver_beta {
ip_hash;
server localhost:8082 fail_timeout=1m;
#server localhost:8081 backup; # backup and weight aren't working with the ip_hash directive
}
geo $beta_user {
default stable;
10.17.12.246 beta;
}
map $beta_user $upstream {
stable dataserver_stable;
beta dataserver_beta;
}
server {
listen 81;
server_name localhost;
set_real_ip_from 27.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location / {
error_page 502 504 @fallback;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $realip_remote_addr;
proxy_pass http://$upstream;
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
}
location @fallback {
proxy_pass_intercept_errors on;
proxy_pass http://dataserver_stable;
}
}
}