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

标签 docker nginx docker-swarm high-availability

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

在这种情况下,我们想再次重试相同的端点。我们怎样才能实现这一目标?

According to this我们使用主机的私有(private) 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服务发现,这里是否需要upstream?

最佳答案

我建议您直接在容器级别添加运行状况检查 ( here )

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

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

关于docker - Nginx 在 Docker 服务发现中的 http_502 上重试相同端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53274144/

相关文章:

Nginx 的速度,以及如何复制它

docker - docker swarm relabel实例中的Prometheus dns服务发现

docker - 使用 docker-machine 设置 Swarm 时出现问题

Docker 服务陷入新状态(Swarm)

django - 如何配置 Pydev 测试运行器以使用 Docker

bash - 需要简单的脚本来删除所有超过 4 周的 docker 镜像

Wordpress wp-config.php 不会在 Dockers 中更新?

docker - ci/cd中断go get测试

nginx - (ubuntu)nginx:[emerg] bind()到0.0.0.0:80失败(13:权限被拒绝)

nginx - 使用Nginx的docker-compose无法正常工作