我们使用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再次。
其他查询:
- docker swarm 有没有办法让它停止指向服务发现中的更新服务,直到该服务完全启动?
- 既然我们直接使用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/