Nginx 在 Docker 服务发现中重试 http_502 上的相同端点

Nginx retry same end point on http_502 in Docker service Discovery

我们将 docker swarmservice discovery 用于后端 REST 应用程序. swarm中的服务配置为endpoint_mode: vip,在global模式下为运行。 Nginx 是通过服务发现别名传递的代理。当我们更新后端服务时,有时 nginx 会抛出 502,因为服务发现可能指向更新服务。

在这种情况下,我们想再次重试同一个端点。我们怎样才能做到这一点?

According to this 我们使用主机的私有 IP 添加上游并使用 proxy_next_upstream error timeout http_502; 但问题仍然存在。

nginx.conf

upstream servers {
    server 192.168.1.2:443; #private ip of host machine
    server 192.168.1.2:443 backup;
}

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    proxy_next_upstream http_502;
    location /endpoint1 {
        proxy_pass http://docker.service1:8080/endpoint1;
    }
    location /endpoint2 {
        proxy_pass http://docker.service2:8080/endpoint2;
    }
    location /endpoint3 {
        proxy_pass http://docker.service3:8080/endpoint3;
    }
}

如果再http://docker.service1:8080/endpoint1 throws 502 we want to hit http://docker.service1:8080/endpoint1这里。

其他查询:

  1. 在 docker swarm 中有什么方法可以让它停止指向服务发现中的更新服务,直到该服务完全启动为止?
  2. 直接使用docker服务发现,这里需要上游吗?

我建议您直接在容器级别添加健康检查(here)

这样做,docker 会定期对您指定的端点执行 ping 操作,如果发现它不健康,它将 1) 停止向其路由流量 2) 终止容器并重新启动一个新容器。因此,您的上游将被解析为健康容器之一。无需重试。

至于您的其他问题,第一个问题 docker 在正常之前不会开始路由。第二,nginx 在根据端点 url 分配流量方面仍然很有用。但就个人而言,nginx + swarm vip 模式不是一个很好的选择,因为 swarm 负载均衡器的文档很少,它不支持粘性会话并且你不能进行代理级别的健康检查,我会使用 traefik 代替,它有它自己的负载平衡器。