logo NodeSeekbeta

终于是解决了ESA的黑洞IP问题了:自动维护边缘 IP 池

适用场景:站点套了阿里云 ESA(同类还有腾讯云 EdgeOne、Cloudflare),大陆用户偶发「打不开 / 转圈」。
环境预设:云函数与域名解析在同一个账号、同一个中国大陆地域(不同区也可以做,只是要多配一步跨区调用)。

一、问题出在哪(原理)

  1. ESA 给的接入目标(本站实际用的就是 www.say.li.a1.inittt.com)返回的不是固定的几个 IP,而是一批边缘 IP;
  2. 这批 IP 按「请求来源的运营商 / 地域」分发 —— 同一个域名,联通可能解析到 16 个、电信只有几个,用公共 DNS 与用运营商自带 DNS 结果也可能不同;
  3. 其中有一部分 IP 从中国大陆方向完全不可达(TCP 443 无响应,俗称「黑洞」);
  4. 客户端每次冷解析都会从池里随机挑一个:
    • 命中好 IP → 秒开;
    • 命中黑洞 → 几十秒无响应 / 打不开。
  5. 而接入目标那批记录的 TTL 很短,缓存一过期就重新抽签 —— 于是表现为「有时能开、有时打不开」,且换网络 / 换设备结果还不一样。

一句话:问题不在 CDN 本身,而在「客户端每次都要从一批好坏混杂的 IP 里抽签」。

二、解决思路

不要让域名直接 CNAME 到接入目标(那等于把含黑洞的整个池丢给客户端抽签);
改成让 DNS 只回答「当前确定可用的 IP」,并用云函数定时刷新这份清单。

          查询 www.say.li
客户端 ──────────────► 你的 DNS(分线路解析)
                        ├─ 联通线路 → A 记录 = 当前可用 IP   ← 云函数自动维护
                        ├─ 电信线路 → A 记录 = 当前可用 IP   ← 云函数自动维护
                        └─ 默认线路 → CNAME → Cloudflare(境外用户)

云函数(大陆地域、定时触发,例如每 30 分钟)
  ① 解析接入目标,取候选 IP
  ② 逐个 TCP 443 探测
  ③ 把「可用的那一批」写回 A 记录

三、三个关键设计(原理)

  1. 候选池 = 解析结果 ∪ 静态候选池
    因为调度域只按来源返回子集,光靠解析可能只拿到 1 个,必须再放一份「已知 IP 清单」兜底。
  2. 保护阈值:可用 IP 数少于阈值就拒绝改动(防止异常时把记录清空)。
    建议把阈值设为 1 —— 这样「只剩 1~2 个可用」时也会写进去,用户永远命中可用节点;且坏 IP 恢复后会自动加回(自愈)。
  3. 只动指定线路:只改你指定的那几条(如联通 / 电信),不碰其它 CNAME 线路(CF / 其它 CDN)。

四、极简做法

  1. 建子用户:华为云 IAM → 创建用户 → 只授 DNS 权限(DNS FullAccess)→ 下载 AK/SK(SK 只显示一次);
  2. 记项目 ID:华为云控制台右上角账号名 →「我的凭证」→ 项目列表 → 抄下你所在区域的项目 ID;
  3. 给目标线路建 A 记录:在华为云云解析 DNS 控制台里,先把该线路原有的 CNAME 删掉(同一名字 + 同一线路下 A 与 CNAME 冲突)→ 再新建 A 记录,值先随便填 1~2 个可用 IP(后面交给函数自动补齐);
  4. 打包依赖:用与函数运行时相同版本的 Python(例如容器 python:3.10-slim)安装 huaweicloudsdkcore + huaweicloudsdkdns,压成 zip,并先自检能 import 成功;
  5. 在华为云 FunctionGraph(函数工作流)里建函数:事件函数 / 入口 index.handler / 内存 128MB / 执行超时调到 120 秒(默认值太小会直接超时)/ 依赖与代码一起上传(同一目录即可 import,但别漏 index.py);
  6. 加定时触发器(固定频率 30 分钟,或 Cron 0 0/30 * * * ?)。

五、核心逻辑(伪代码,照这个写就行)

pool  = 解析(接入目标) ∪ 静态候选池        # ① 取候选
good  = [ip for ip in pool if tcp443(ip)]  # ② 探测
if len(good) < 1: return                   # ③ 保护:一个可用都没探到,就别动 DNS
for line in ["联通", "电信"]:              # ④ 写回
    找到该线路的 A 记录 → 整表覆盖为 good

六、几个坑(踩过才知道)

  • 函数必须部署在中国大陆地域 —— 在境外跑看不到那批黑洞,会把所有 IP (包括黑洞)都判成「可用」,等于白跑;
  • 函数不会自己跑 —— 没有定时触发器就永远不执行;
  • 默认执行超时偏小(华为云默认 3 秒)—— 冷启动 + 探测必然被掐断,要调到 120 秒;
  • 依赖包的 Python 版本必须与运行时一致 —— 否则二进制扩展 import 会失败;
  • 免费额度完全够用:FunctionGraph 每月 100 万次请求 + 400,000 GB·秒(128MB 档折算 = 320 万秒),30 分钟一轮一个月只占 0.2% 左右。

七、效果

上线后:联通 / 电信用户永远命中可用 IP(首字节几百毫秒级);坏 IP 恢复、新 IP 加入都会被下一轮自动纳入 ——「可能随机打不开」这件事从根上消失。


虽然是由AI整理,但应该不影响大家阅读,本贴由 SAY(S站)原创 + 实操全盘通过,转贴请注明出处。
https://www.say.li/topic/23

  • 也可以在国内部署一台VPS来实现同样的效果(需要huaweicloud API)。
    但有免费的FunctionGraph可以用啊,今晚测试了几小时全部正常工作:
    image

  • 如果是备案域名完全不用这么麻烦 因为边缘是阿里国内服务器

  • @机长 #2 是的,备案没有这个问题了,全走CN
    但我一个朋友的备案域名也加不进去,不明白为什么。

你好啊,陌生人!

我的朋友,看起来你是新来的,如果想参与到讨论中,点击下面的按钮!

📈用户数目📈

目前论坛共有73246位seeker

🎉欢迎新用户🎉