Cloudflare Worker 负载均衡(WeChat-AI 多节点)
把主域名反代到多台源站 Docker 节点,做健康检查 + 轮询分流。
源站地址只写在本 Worker 的 ORIGINS 里;应用内 PUBLIC_BASE_URL 一律填主域名。管理后台「节点」页显示的是 Redis 注册的进程,不展示源站 URL。
为什么 API 会慢 3~5 秒?(即使没配测活变量)
旧版 Worker 在每次用户请求里都会 await 健康检查:
- 代码默认
HEALTH_PATH=/health/ready(会 ping Redis) - 默认超时约 3s
- Cloudflare isolate 几乎不跨请求复用内存 → 探活缓存经常是冷的
- 结果:用户 API 先等探活,再访问源站 → 固定多 1~3s+
与是否配置 HEALTH_* 变量无关——变量只是覆盖默认值,默认本身就会探活。
其它次要因素:用户 → CF POP → 源站 IP 多一跳 RTT(通常几十~几百 ms,一般到不了 3~5s)。
已修复(请重新粘贴最新 worker.js 并 Deploy)
- 请求路径不再 await 探活;用
waitUntil后台探活 - 默认探活改为轻量
/health - 默认乐观转发(先当全健康 round-robin)
- 仅代理失败 / 502–504 时快速试下一台
部署后自检:https://主域名/__lb/health 应含 "mode":"non_blocking_probe"。
DevTools 看 /api/v1/... 的 TTFB 应接近直连源站。
架构
浏览器 ──► 主域名 (CF Worker)
├─► http://node1:8787
├─► http://node2:8787
└─► …
└── 共享 REDIS_URL
方式 A:Cloudflare 控制台(Hello World,推荐上手)
Dashboard 不能直接上传整个 src/ 文件夹;「Upload your static files」是静态站,不是 Worker 逻辑。
- 创建 Worker → 从 Hello World! 开始
- 打开在线编辑器,整份替换为仓库里的
worker.js(单文件,已合并 LB 逻辑) - Save and Deploy
- Worker → Settings → Variables and Secrets 添加:
| 名称 | 类型 | 示例 |
|---|---|---|
ORIGINS |
Text | http://1.2.3.4:8787,http://5.6.7.8:8787 |
HEALTH_PATH |
Text(可选) | /health(默认;勿用 ready 除非你清楚) |
HEALTH_INTERVAL_MS |
Text(可选) | 15000(后台探活间隔) |
HEALTH_TIMEOUT_MS |
Text(可选) | 1500 |
HEALTH_ON_REQUEST |
Text(可选) | 默认关;true 会恢复慢路径,勿开 |
ORIGIN_HOST_MODE |
Text(可选) | preserve |
ORIGIN_PROXY_SECRET |
Secret(可选) | 随机长串 |
ADSENSE_CLIENT |
Text(可选) | 如 ca-pub-…;有值则注入广告脚本 |
ADSENSE_ENABLED |
Text(可选) | 默认 true;设 false 关闭注入 |
ADSENSE_SKIP_PATHS |
Text(可选) | 默认 /admin,/api/,/__lb/,/cdn/,/health |
ADSENSE_ADS_TXT |
Text(可选) | 自定义 ads.txt 全文;空则按 CLIENT 自动生成 |
- Settings → Domains & Routes / Custom Domains 绑定主域名
- 自检:
https://你的主域名/__lb/health
若编辑器固定文件名 worker.js:把本仓库 cloudflare-worker/worker.js 内容粘进去即可。
方式 B:Wrangler CLI(多文件 TS)
cd cloudflare-worker
npm install
# 编辑 wrangler.toml [vars] ORIGINS,或:
npx wrangler secret put ORIGIN_PROXY_SECRET # 可选
npx wrangler deploy
必填
| 变量 | 说明 |
|---|---|
ORIGINS |
逗号分隔源站根地址,如 http://1.2.3.4:8787,http://5.6.7.8:8787 |
可选
| 变量 | 默认 | 说明 |
|---|---|---|
HEALTH_PATH |
/health |
后台探活路径(轻量;不要用 ready 除非必要) |
HEALTH_INTERVAL_MS |
15000 |
后台探活间隔(不阻塞用户请求) |
HEALTH_TIMEOUT_MS |
1500 |
探活超时 |
HEALTH_ON_REQUEST |
关 | true 时每次请求 await 探活(慢,仅调试) |
ORIGIN_HOST_MODE |
preserve |
preserve 转发用户 Host;origin 改写为源站 Host |
ORIGIN_PROXY_SECRET |
— | 若设置,注入请求头 X-WeChat-AI-Proxy-Secret |
ADSENSE_CLIENT |
— | AdSense 发布商 ID(ca-pub-…);设置后对公开 HTML 注入脚本 |
ADSENSE_ENABLED |
true |
false 时关闭注入(即使配置了 CLIENT) |
ADSENSE_SKIP_PATHS |
见上 | 不注入广告的路径前缀(逗号分隔) |
ADSENSE_ADS_TXT |
自动 | 覆盖边缘返回的 /ads.txt 内容 |
Google AdSense(边缘注入)
Worker 在不改源站 HTML 的前提下:
-
对成功的
text/html响应,用HTMLRewriter在<head>末尾注入:<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-…" crossorigin="anonymous"></script> -
直接响应
/ads.txt(不必源站提供),默认内容:google.com, pub-…, DIRECT, f08c47fec0942fa0 -
默认跳过
/admin、/api/*、/__lb/*、/cdn/*、/health(管理后台与 API 不插广告) -
注入后的响应带
X-WeChat-AI-Adsense: 1;GET /__lb/health的 JSON 含adsense.enabled/adsense.client
控制台粘贴 worker.js 时,在 Variables 里加上 ADSENSE_CLIENT。关闭:清空 ADSENSE_CLIENT 或设 ADSENSE_ENABLED=false 后重新 Deploy。
自检:
# 应看到 adsense.enabled / client
curl -s https://你的主域名/__lb/health
# 应返回 google.com, pub-… 行
curl -s https://你的主域名/ads.txt
# 首页 HTML 的 <head> 应含 pagead2.googlesyndication.com
curl -s https://你的主域名/ | head -n 40
说明:这是 Auto ads 用的全局脚本;若要用手动广告位,仍需在页面 HTML 里放 <ins class="adsbygoogle">(或再扩展 Worker 注入广告位)。
本地调试
# 终端 1/2:两台源站(不同端口,同一 REDIS_URL)
# 终端 3:
npx wrangler dev --var ORIGINS:http://127.0.0.1:8787,http://127.0.0.1:8788
Worker 自检:GET /__lb/health → mode: non_blocking_probe。
DNS
- 主域名 Custom Domain 绑到本 Worker(或 CNAME 到 workers.dev 路由)。
- 源站 IP 不必 橙云代理到用户;可仅允许 Cloudflare IP 访问 8787。
- 应用
.env:
PUBLIC_BASE_URL=https://你的主域名
LINUXDO_REDIRECT_URI=https://你的主域名/api/v1/auth/callback
COOKIE_SECURE=true
WORKER_ID=node-01 # 每机唯一
与 Cache Rules
源站仍输出 Cache-Control / Cloudflare-CDN-Cache-Control。全站经 Worker 时,可继续用 Dashboard Cache Rules 缓存 HTML 壳与 /cdn/s/*(见 docs/cloudflare.md)。
算法摘要
- 解析
ORIGINS - 按间隔对
HEALTH_PATH探活,标记 healthy - 在 healthy 集合 round-robin;全挂时仍尝试一次
- 转发 Cookie / Method / Body;附加
CF-Connecting-IP、X-Forwarded-* - 响应增加
X-WeChat-AI-LB: 1(标识经 LB);不向客户端暴露源站主机名 - 若配置了 AdSense:公开 HTML 注入脚本;
/ads.txt由边缘直接返回
扩缩容
- 新机器
docker run同镜像,配同一REDIS_URL/PUBLIC_BASE_URL,唯一WORKER_ID - 更新 Worker
ORIGINS并wrangler deploy - 管理后台 节点 页应出现新
WORKER_ID心跳
下线:从 ORIGINS 移除 → deploy;停容器后租约 TTL 过期自动转移 bot。