第一种方式: 域名
server {
...
proxy_pass http://dev.foxchan.com:10086;
...
}
缺点: 如果ip发生变化,此处nginx就无法反向代理了,必须重启一次nginx才行。
原因: nginx在第一次解析域名后,会缓存该域名的信息,并且不会主动更新
第二种方式 :resolver 配合set
server {
...
resolver 127.0.0.1 valid=5 ipv6=off;
set $backend "http://dev.foxchan.com:10086";
proxy_pass $backend;
...
}
优点:用 set 设置一个变量,通过 resolver 实现每次访问都解析新的ip地址,解决了ip地址缓存的问题。
resolver 可以设置多个公共DNS,也可以设置自建dns加速解析
valid 单位是s,表示间隔多久更新dns解析
ipv6 nginx 从1.11.5 开始自动启用了ipv6,resolver 就会同时查询 IPv4 和 IPv6 的 DNS 记录,如果没有ipv6 的 记录,需要手动关闭
第三种方式 :模块ngx_upstream_jdomain
http {
resolver 127.0.0.1;
resolver_timeout 10s;
upstream test {
jdomain www.foxchan.com port=8080 interval=10; #指定域名和端口,每隔10秒进行一次解析
server 127.0.0.1:5555 backup;
}
server {
listen 8888;
location / {
proxy_pass http://test;
}
}
server {
listen 5555;
return 502 'Panic!';
}
}
注意:
通过这种方式代理到后端的服务,后端服务接收到的$host的值即为test,如果后端服务以主机头的方式来接受服务,这显然是不能接受的。所以在代理配置中,必须加上如下配置以将主机头传递给后端服务器:
proxy_set_header Host $host;
第四种方式 :Tengine
使用淘宝的Tengine模块,ngx_http_upstream_dynamic_module
upstream backend {
dynamic_resolve fallback=stale fail_timeout=30s;
server a.com;
server b.com;
}
server {
...
location / {
proxy_pass http://backend;
}
}
fallback参数指定了当域名无法解析时采取的动作:
stale 使用tengine启动的时候获取的旧地址
next 选择upstream中的下一个server
shutdown 结束当前请求
fail_timeout 指定了将DNS服务当做无法使用的时间,也就是当某次DNS请求失败后,假定后续多长的时间内DNS服务依然不可用,以减少对无效DNS的查询。
第五种方式 :Nginx Plus
有2种方式通过dns 做服务发现
A记录
resolver 10.0.0.2 valid=10s;
upstream backends {
zone backends 64k;
server backends.example.com:8080 resolve;
}
server {
location / {
proxy_pass http://backends;
}
}
SRV
记录
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;
}
}
官方文档:https://www.nginx.com/blog/dns-service-discovery-nginx-plus/
漏洞:
此漏洞存在于 nginx 的 DNS 解析模块,并且仅在配置文件中使用"resolver"指令时才会影响 nginx。***者可以利用该漏洞进行远程 DDoS ***,甚至远程执行。