源于我提给雷池的一个 issue。如果你想跟进这个 issue,请访问 [建议] DDNS 域名回源场景优化 / 动态解析 upstream 的域名 #384

20231203235507

我在公网有一台机器装了雷池,反代我的 HomeLab 中的 NGINX,以使得将家宽的非标准端口转换成标准端口。

家宽是动态 IP,因为 NGINX 的机制,默认情况下,NGINX 会在 start/reload 时解析 upstream 里的 server, 并缓存 ip,如果 NGINX 的 Worker 已经 Running 了,此时你在修改 server 中域名的解析结果,实际它是不生效的,仍然会缓存老记录。

我想了几种办法:

方案 1:定时 reload 雷池的 NGINX。这个方法直接被 PASS 掉了。在业务高峰频繁 reload NGINX,不是一个好办法,可能会导致 worker 卡死。而且比如我 1 分钟 reload 一次 NGINX,那最多会导致业务恢复时间<=60 秒。

方案 2:在雷池的机器上起一个 Webhook 服务,当 HomeLab 出口 IP 变化的时候,由于要更新 IP,执行 DDNS 脚本,所以顺带着触发一下 reload 雷池 NGINX 的 Webhook 服务。这个方法也有弊端,当 DDNS 脚本触发,reload 雷池 NGINX 的时候,此时 DNS 可能还有缓存(TTL)没过期,导致 reload 的时候,解析到的还是老 IP,这就刷了个寂寞。

方案 3:开启 Tengine 的动态域名解析。修改雷池的配置,使得其支持动态域名解析。这也是我目前再用的方案。如果你的雷池安装目录是/data/safeline,则需要修改/data/safeline/resources/nginx/sites-enabled文件夹中网站的配置,注意,改完这个配置就不要去动管理端了,在雷池管理端增删网站,会导致配置被覆盖。

在 upstream{} 中增加一行 dynamic_resolve fallback=stale fail_timeout=30s;,保存退出。

执行 docker exec safeline-tengine nginx -t 当提示 test is successful 时候,执行docker exec safeline-tengine nginx -s reload

20231204001542

此时动态域名解析就生效了。