在配置NGINX的时候,upstream,proxy_pass都是极其常用的指令,我们很多时候通过简单的搜索或者查看文档就实现了工作需求,但是这两个命令实际上有着非常多的细节,我们需要更多掌握这些细节才能更好的把控NGINX和解决工作遇到的问题,所以让我们做一些深入的研究与测试,今天此文和大家一起看看upstream下的秘密。
1.我们经常这样配置:proxy_pass http://www.example.com ,看上去一切工作ok,好了可以打游戏了。然后突然有一天你就发现,业务怎么访问不了了,为啥客户端被返回了502? 一通研究发现,是域名对应的IP发生了变化。在上述方法中,实际上仅在配置加载后利用操作系统的dns server解析一次,然后持续缓存(这里大家还可以研究下配置加载后到第一次访问之前是否有缓存),后续并不主动更新域名对应的IP,且启动或加载配置时候,如果解析不了,则无法启动。因此有很大局限性,比如在paas里用svc,云上用elb
2. 有时候我们还会这样配置,在upstream里使用域名,如下,这种方式和第一种类似,缓存解析,只有reload配置或重启时候才会更新解析,且无法解析时候会导致无法启动。但是好处是可以使用upstream里的功能参数,例如配置负载均衡算法等
1 2 3 4 5 6 7 8 9 10 |
upstream backends { least_conn; server backends.example.com:8080 max_fails=3; } server { location / { proxy_pass http://backends; } } |
3. 那怎么解决这个dns解析的缓存问题呢,是不是在配置加上resolver就能解决?比如下面这样配置是否可行?
1 2 3 4 5 6 7 |
resolver 10.250.0.53 valid=3s; server { location /gotohelloworld { proxy_pass https://backends.example.com; } } |
测试结果表明这种配置并不可以。
注意:
如在proxy_pass里使用变量,这可以帮助解决自动更新解析的问题,这样同样必须指明resolver。这种方式实际效果是每次请求都会做dns解析。同时这种方法无法配置类似第2种里的LB算法等效果。 :
1 2 3 4 5 6 7 8 |
resolver 8.8.8.8 valid=10s; server { location / { set $servers github.com; proxy_pass http://$servers; } } |
4. 但是对于3的那种配置方法,如果upstream里需要配置很多个不同的上游域名就比较麻烦了,例如下面这个配置方法
1 2 3 4 5 |
resolver 10.250.0.53 valid=3s; upstream apidemo2backends { server svc.a.com; server svc.b.com; } |
在上述配置中,我们可以看到有resolver配置,但是实际中这种配置经过测试一样无法刷新DNS解析缓存,会导致nginx无法链接后端服务。
5. 那如何既能使用upstream 来定义server group实现复杂配置,同时又能满足动态实时解析更新呢。nginx plus具有这样的能力,resolve参数是nginx plus特有功能。
1 2 3 4 5 6 7 8 9 10 11 12 |
resolver 10.0.0.2 valid=10s; upstream backends { zone backends 64k; server backends.example.com:8080 resolve; } server { location / { proxy_pass http://backends; } } |
6. 如果企业应用大量使用srv记录注册服务信息,例如k8s内,那么nginx plus也支持使用srv记录来发现服务配置,例如优先级,权重,端口号。 优先级可用于控制配置backup server,权重可用于lb分配
1 2 3 4 5 6 7 8 9 10 11 12 |
resolver 10.0.0.2 valid=10s; upstream backends { zone backends 64k; server backends.example.com service=_http._tcp resolve; } server { location / { proxy_pass http://backends; } } |
7. 最后一种动态更新后端的方法就是使用nginx plus的api来直接动态修改,这个方法比较直接,非常适合自动化变更与部署,或者通过企业的devops pipeline来纳入,当upstream发生变化时,直接自动调用相关API进行变更配置,也非常适合在公有云上和scale group配合。
文章评论