前言
我家是电信的公网ip,有公网但是没有80和443,更别说备案了,这怎么办呢。正好前几天在 VMRack 的交流群里抽中了一台C2G2的三网精品(电信: CN2 GIA/联通: CU9929/移动: CMIN2)一年的机器,用来做nginx转发完全够了呀!
于是我立马行动,很快的做好了nginx反向代理和域名的备案,就是你们现在所看到的这个站(www.cmnode.com,假如是ifengdian的话应该是bing收录爬取到非公开的了)。
但是我发现家里的公网ip一变动,ifengdian.top的ddns解析也会一起跟着动,按理说只需要等待10分钟,ttl过去后反代的www.cmnode.com就可以正常访问了呀,可是为啥一变动后就会502呢,而且一重启nginx就就可以了。
nginx只会在启动时候进行一次域名解析,导致ddns更新后还是连接原ip。
Nginx 502 错误及动态解析解决方案
一:错误原因总结:
您的家中 IP 变动。
DDNS 服务(如 $ifengdian.top$ 的解析)立即更新,指向新的 IP。
阿里云服务器上的 Nginx 没有重启,它仍然缓存着旧的家庭公网 IP 地址。
Nginx 尝试连接旧 IP,连接失败,返回 502 Bad Gateway。
您手动重启 Nginx 时,它会重新解析 $ifengdian.top$,获取到新 IP,恢复正常。
二:核心解决方案:使用变量和 Resolver
要让 Nginx 在处理每一个请求时都进行动态域名解析,而不是只在启动时解析一次,您需要进行以下两个关键修改:
1:将 proxy_pass 的域名改为变量
当 proxy_pass 的值是一个变量时,Nginx 就不会在启动时解析它,而是在每次请求到达时才去解析。
修改前的配置(旧):
location / {
# Nginx 启动时解析并缓存这个域名对应的IP
proxy_pass http://ifengdian.top;
# ... 其他配置
}修改后的配置(新)
server {
# 1. 在 server 块中定义一个变量
set $backend_home "http://ifengdian.top";
location / {
# 2. proxy_pass 使用这个变量
proxy_pass $backend_home;
# ... 其他配置
}
}2:配置 Resolver 和 TTL (生存时间)
光用变量还不够,您还需要告诉 Nginx 使用哪个 DNS 服务器去解析这个变量,以及解析结果可以缓存多久(TTL)。
在 server 块内(或 http 块内)添加以下配置:
http {
# 定义 Nginx 用哪个 DNS 服务器去解析域名
# 推荐使用公共 DNS 或您所在云服务商的 DNS
# valid=5s 表示解析结果在 Nginx 中只缓存 5 秒
resolver 114.114.114.114 8.8.8.8 valid=5s;
server {
listen 80;
server_name blog.dimeta.top;
# 定义变量
set $backend_home "http://ifengdian.top";
location / {
# 使用变量进行反向代理
proxy_pass $backend_home;
# ... 其他配置,例如 headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 解决 Nginx 在解析 DNS 时,如果 upstream 有多个 IP 导致的问题
# 这一行通常不是必须的,但在某些复杂场景下很有用
# proxy_set_header Connection "";
}
}
}总结
通过在 Nginx 配置中引入 set 变量和 resolver 指令,您就将 Nginx 的解析机制从**“启动时静态解析”转换为了“运行时动态解析”**。
这样,当您家中的公网 IP 变动,DDNS 更新解析记录后,Nginx 在下一次请求到达时(最长等待 $valid$ 设置的时间,即 $5$ 秒),就会去 DNS 服务器拉取最新的 IP 地址,您的博客就能继续正常访问,无需手动重启 Nginx 了。