如何配置Nginx使其在使用upstream块时,即使上游主机宕机仍能正常启动
如何配置Nginx使其在使用upstream块时,即使上游主机宕机仍能正常启动
我太懂你这种糟心的感觉了——明明只是某台上游服务器临时挂了,结果整个Nginx都启动不了,直接导致整个系统瘫痪,简直离谱!针对你用upstream块的场景,其实有个非常直接的解决办法,下面给你一步步讲清楚:
首先得搞懂问题根源:默认情况下,Nginx在启动时会立即解析upstream块里所有上游节点的域名,只要有一个域名解析失败或者主机不可达,Nginx就会启动失败。我们要做的,就是把域名解析的时机从启动阶段推迟到请求阶段,这样启动时就不会卡在上游节点的可用性校验上了。
最推荐的方案:给upstream节点加resolve指令
这个方法从Nginx 1.1.9版本开始支持,算是官方给出的标准解决方案,完美适配upstream块的场景:
- 先在
http块里配置DNS解析器(可选,但推荐,能让解析更稳定):
http { # 用公共DNS,也可以换成你自己的内部DNS服务器 resolver 8.8.8.8 8.8.4.4 valid=300s; # valid=300s表示解析结果缓存5分钟,减少DNS查询次数
- 然后在你的
upstream块里,给每个上游服务器加上resolve参数:
upstream backend_servers { server backend1.example.com resolve max_fails=3 fail_timeout=30s; server backend2.example.com resolve max_fails=3 fail_timeout=30s; # max_fails和fail_timeout是健康检查参数:30秒内失败3次就标记节点不可用,30秒后再重试 }
- 最后是常规的
server和location配置,和你之前的写法一样就行:
server { listen 80; server_name your-domain.com; location / { proxy_pass http://backend_servers; proxy_set_header Host $host; # 其他你需要的proxy配置,比如proxy_connect_timeout这些 } } }
这个配置的妙处在哪?
- Nginx启动时只会读取
upstream的配置结构,不会去解析域名或者校验节点可用性,所以哪怕所有上游节点都宕机,Nginx也能正常启动。 - 每次有请求进来时,Nginx才会去解析上游节点的域名,配合
max_fails和fail_timeout,自动跳过不可达的节点,请求只会分发到正常的节点上。 - 如果上游节点的IP地址变了,Nginx会自动用新的解析结果,不需要重启服务。
如果你用的是旧版本Nginx(不支持upstream里的resolve)
如果你的Nginx版本低于1.1.9,没法用上面的方法,那可以用变量模拟upstream的负载均衡效果,把每个上游节点的地址存在变量里,再配合split_clients做简单的负载均衡:
http { resolver 8.8.8.8; # 用split_clients做轮询负载均衡,把请求分到不同的上游节点 split_clients $request_uri $backend { 50% backend1.example.com; 50% backend2.example.com; } server { listen 80; server_name your-domain.com; location / { proxy_pass http://$backend; proxy_set_header Host $host; } } }
不过这种方法的负载均衡能力比较有限,没有upstream块的ip_hash、least_conn这些高级策略,所以还是建议尽量升级Nginx版本用第一种方案。
备注:内容来源于stack exchange,提问作者shawmanz32na
相关产品推荐
相关产品推荐

