Nginx不会以上游未找到的主机开始

rin*_*inu 32 nginx http-proxy

我使用nginx代理并为我保持远程服务器的持久连接.

我已经配置了大约15个与此示例类似的块:

upstream rinu-test {
    server test.rinu.test:443;
    keepalive 20;
}
server {
    listen 80;
    server_name test.rinu.test;
    location / {
        proxy_pass https://rinu-test;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $http_host;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是如果无法在一个或多个upstream块中解析主机名,则nginx将不会(重新)启动.我也不能使用静态IP,其中一些主机明确表示不会这样做,因为IP会发生变化.我看到这个错误消息的每个其他解决方案都说要摆脱upstream并在location块中做所有事情.这不可能,因为keepalive只有在upstream.

我可以暂时承受失去一台服务器但不是全部15台.

编辑:结果nginx不适合这个用例.应使用备用后端(上游)keepalive代理.我的答案是自定义Node.js替代方案.到目前为止,我还没有找到其他任何实际可行的替代方案.

nba*_*ari 10

您的情况与使用 awsELB作为上游的情况非常相似,其中resolve对定义域的正确 IP至关重要。

您需要做的第一件事是确保您使用的 DNS 服务器可以解析到您的域,然后您可以像这样创建配置:

resolver 10.0.0.2 valid=300s;
resolver_timeout 10s;

location /foo {
    set $foo_backend_servers foo_backends.example.com;
    proxy_pass http://$foo_backend_servers;
 }

location /bar {
    set $bar_backend_servers bar_backends.example.com;
    proxy_pass http://$bar_backend_servers;
 }
Run Code Online (Sandbox Code Playgroud)

请注意,resolver 10.0.0.2它应该是可以工作并回答您的查询的 DNS 服务器的 IP,这取决于您的设置,这可能是本地缓存服务,例如unbound。然后只需使用resolve 127.0.0.1

现在,使用变量来指定域名非常重要,来自文档:

当您在 proxy_pass 指令中使用变量指定域名时,NGINX 会在其 TTL 到期时重新解析域名。

您可以使用以下工具检查解析器dig

$ dig +short stackoverflow.com
Run Code Online (Sandbox Code Playgroud)

如果必须keepalive在上游使用,并且不是使用 Nginx + 的选项,那么您可以尝试使用openresty balancer,您将需要使用/实现lua-resty-dns


cns*_*nst 7

这已经通电全球访问量最大的网站数量庞大(有的还在做甚至nowdays,如果服务器头是可以相信的)nginx的(1.1.4之前)的早期版本,甚至没有支持keepaliveupstream侧,因为在数据中心设置中这样做几乎没有好处,除非您在各个主机之间有不平凡的延迟。有关某些说明,请参见https://serverfault.com/a/883019/110020

基本上,除非您知道在上游和前端之间特别需要保持连接,否则很有可能只会使您的体系结构的弹性降低且状况恶化。

(请注意,您当前的解决方案也是错误的,因为IP地址的更改同样不会被检测到,因为您仅在配置重新加载时进行主机名解析;因此,即使nginx确实启动了,一旦IP地址也将基本上停止工作的上游服务器确实发生了变化。)

潜在的解决方案,选择一种:

  • 最好的解决方案似乎只是消除了upstream keepalive在数据中心环境中不必要的可能,并proxy_pass为每个请求使用具有最新DNS解析度的变量(nginx仍然足够聪明,仍然可以缓存此类解析度)

  • 另一种选择是通过商业订阅获得nginx的付费版本,该订阅在上下文中具有resolveserver指令的参数upstream

  • 最后,另一种尝试是使用set变量和/或a map来指定其中的服务器upstream;既未确认也未拒绝执行;例如,它可能会或可能不会。

  • 变量不能用于定义上游服务器。 (2认同)
  • 全球大约有 100 家独立服务提供商,主要分布在美洲和欧洲。有几个是并行查询的,最多我见过大约 20 个。在一个服务提供商的示例中,平均响应时间从 1.3 秒下降到 0.5 秒。最低增益为 150 毫秒。到目前为止,keepalive 代理的速度没有变慢。该应用程序是在 PHP 中,它可以并行发出请求,但由于它的生命周期很短,因此无法保持连接打开。 (2认同)
  • @rinu,我不知道您如何通过 keepalive 对连接的单次重用节省 1.3 秒,似乎您可能正在衡量除了 keepalive 节省之外的其他东西。另外,我对这里的用例有点困惑——你基本上是想通过 PHP 查询 100 个独立的提供者,并使用 nginx 作为连接缓存?然后,您的问题对于您要完成的任务的表述非常糟糕,因为还有许多其他更好的方法可以进行 keepalive,甚至可能使用 nginx 流 - 您通过不完整的规范不公平地限制了解决方案的范围。 (2认同)