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

时间:2018-11-13 05:05:24

标签: docker nginx docker-swarm high-availability

我们将 docker swarm 服务发现一起用于后端 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抛出 502 ,我们想再次击中http://docker.service1:8080/endpoint1

其他查询:

  1. docker swarm中是否有任何方法可以使其停止指向服务发现中的更新服务,直到该服务完全启动?
  2. 由于我们直接使用docker服务发现,因此上游是否必要?

1 个答案:

答案 0 :(得分:2)

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

这样做,docker会定期ping您指定的端点,如果发现该端点不健康,它将1)停止将流量路由到该端点2)杀死该容器并重新启动一个新容器。因此,您将在上游解决健康容器之一。无需重试。

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