一个专业运
维技术分享!

Nginx反向代理DNS缓存问题

故事是这样的:

有一台内网服务器,电信宽带有动态的公网IP,所以我配置了DDNS域名,这样公网就可以通过域名访问到家中的内网服务器。

因为电信宽带封禁了常见的80/443端口,所以我在阿里云服务器上配置了nginx做反向代理,但是发现经常502错误,只有重启nginx才能恢复,此时内网服务工作正常。

1 原因

究其原因,在于nginx反向代理解析DDNS域名时,只会在Nginx启动解析配置文件的时候解析1次,此后就会一直拿着解析到的IP连接upstream。因此,当我的电信公网IP变化后,nginx并不会重新去解析DDNS域名,导致连接一个错误的IP。

反向代理nginx配置文件大概是这样的:

server {
listen 443 ssl;
server_name www.xlsys.cn;

ssl_certificate /etc/nginx/ssl/7836194.pem;
ssl_certificate_key /etc/nginx/ssl/7836194.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!ECDHE+3DES:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
charset utf-8;
allow all;

location / {
#转发
proxy_pass http://cdn.xlsys.cn:8899;
# proxy_http_version 1.1;
# proxy_connect_timeout 10s;
#proxy_read_timeout 86400s;
#proxy_send_timeout 80s;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_body_buffer_size 1024k;
client_max_body_size 1000M;
}

2解决方法

我希望每次proxy行为都重新解析IP地址,或者至少可以控制缓存的时间。

要实现这个效果,必须把http://cdn.xlsys.cn:8899;作为变量,这样nginx启动时则不会解析IP,而是运行时解析。

nginx配置文件修改如下:

server {
listen 443 ssl;
server_name www.xlsys.cn;

ssl_certificate /etc/nginx/ssl/7836194.pem;
ssl_certificate_key /etc/nginx/ssl/7836194.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!ECDHE+3DES:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
charset utf-8;
allow all;
#关键配置---------------
#指定 DNS IP,并设置缓存 1-60 秒。
resolver 114.114.114.114 valid=1s;
resolver_timeout 3s;
set $proxy_pass_url http://cqsd.f3322.net:8011;
#关键配置---------------
location / {
#转发配置
proxy_pass $proxy_pass_url;
# proxy_http_version 1.1;
# proxy_connect_timeout 10s;
#proxy_read_timeout 86400s;
#proxy_send_timeout 80s;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_body_buffer_size 1024k;
client_max_body_size 1000M;
}

但这种方法无法作用于 upstream 里的域名。

3使用模块nginx-upstream-dynamic-servers

模块地址: nginx-upstream-dynamic-servers

该模块在第一次启动的时候会进行一次解析,解析完后,在 DNS 服务器设定的 TTL 过期时间内不会再次更新,过期后会再次发起解析请求

使用方法

http {
  resolver 114.114.114.114;

  upstream backend{
    server example.com resolve;
  }
}

使用这种方法的时候,DNS TTL 时间需要设置短一些。

4 使用模块 ngx_upstream_jdomain

文档地址: domain_resolve

ngx_upstream_jdomain 模块是一个依赖 DNS 解析实现的 upstream 负载均衡,该模式下,允许使用域名来写 upstream 后端。该模块默认情况下,会每秒做一次 DNS 解析,使用方法如下

http {
    resolver 8.8.8.8;
    resolver_timeout 10s;

    upstream backend {
        jdomain www.baidu.com port=80 interval=5; # 每 5 秒解析一次
    }
    server {
        listen  8080;
    
        location / {
            proxy_pass http://backend;
        }
    }
}


微信扫描下方的二维码阅读本文

赞(5) 打赏
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。小柳实验室 » Nginx反向代理DNS缓存问题

相关推荐

  • 暂无文章

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏