mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 13:40:45 +00:00
现象:用户早上打开 relay.xxmxxs.top 看到 Cloudflare Error 1033。
watchdog 日志把过程记下来了:
公网不通(HTTP 000,ha_connections=2) <- 隧道显示连着,公网不通
公网不通(HTTP 502,ha_connections=2)
公网恢复(HTTP 200) <- 自己又好了
也就是说:**间歇性假活**,短样本测不出来。
我之前只测 15~25 次就说"可用率 100%",太草率了。
根因:4G 链路会**静默断开** TCP 连接 —— 不发 FIN/RST,双方都以为还连着。
Cloudflare 把请求发到这条僵尸连接上,就回 502/530/1033。
Linux 默认 tcp_keepalive_time = **7200 秒(2 小时)**才发现连接死了,
所以中间这段时间服务一直"看着在线、实际打不开"。
tunnel.log 最近 3000 行的佐证:
i/o timeout 212 次
Retrying connection 127 次
Lost connection 22 次
修法:
1. TCP keepalive 调到 30 秒 + 每 10 秒探测 3 次
=> 最多约 60 秒发现僵尸连接,cloudflared 立刻重连
(/etc/sysctl.d/97-ykxmz-keepalive.conf)
2. 隧道连接数 2 -> 4,多几条冗余
3. 修 relay 从不清理设备记录的问题:
self.devices 只增不减,被控端每换端口/重装就多一条,
实测一天攒了 75 条僵尸记录,/v1/health 从几 KB 涨到 20KB。
加 DEVICE_TTL(6 小时)在 snapshot() 里清掉。
实测(修完立刻验证):
设备侧 公网 15/15 HTTP 200
Windows 公网 25/25,中位 520 ms,最快 463 ms
health 20931 字节 / 75 台 -> 152 字节 / 0 台
48 lines
2.3 KiB
Bash
48 lines
2.3 KiB
Bash
#!/bin/bash
|
|
# 502 但不是 1033:说明 Cloudflare 连上了隧道,是**回源**失败。
|
|
# 本机 curl 200,所以问题在 cloudflared -> relay 这一段。
|
|
set -u
|
|
|
|
echo "════════ 1. 隧道 ingress 配置 ════════"
|
|
cat /root/.cloudflared/config.yml 2>/dev/null | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "════════ 2. relay 到底在听哪个地址 ════════"
|
|
ss -lntp 2>/dev/null | grep -E '8080|LISTEN' | head -8 | sed 's/^/ /'
|
|
echo " ---"
|
|
echo " 127.0.0.1:8080 $(curl -s -o /dev/null -w '%{http_code}' --max-time 5 http://127.0.0.1:8080/v1/health)"
|
|
echo " localhost:8080 $(curl -s -o /dev/null -w '%{http_code}' --max-time 5 http://localhost:8080/v1/health)"
|
|
LANIP=$(hostname -I | awk '{print $1}')
|
|
echo " $LANIP:8080 $(curl -s -o /dev/null -w '%{http_code}' --max-time 5 http://$LANIP:8080/v1/health)"
|
|
|
|
echo
|
|
echo "════════ 3. relay 服务日志(最近 20 行)════════"
|
|
journalctl -u lanremote-relay -n 20 --no-pager 2>/dev/null | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "════════ 4. relay 有没有报错 ════════"
|
|
journalctl -u lanremote-relay -n 100 --no-pager 2>/dev/null \
|
|
| grep -iE 'error|exception|traceback|refused|trace' | tail -8 | sed 's/^/ /'
|
|
echo " (没输出=没有明显报错)"
|
|
|
|
echo
|
|
echo "════════ 5. 本机打一次完整请求,看 relay 怎么回的 ════════"
|
|
curl -sv --max-time 8 http://127.0.0.1:8080/v1/health 2>&1 \
|
|
| grep -E '^< HTTP|^< [A-Z]|^> GET|Connection' | head -10 | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "════════ 6. 隧道 metrics 全量 ════════"
|
|
curl -s --max-time 5 http://127.0.0.1:20241/metrics 2>/dev/null \
|
|
| grep -E '^cloudflared_tunnel' | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "════════ 7. cloudflared 进程和它的命令行 ════════"
|
|
pid=$(pgrep -f 'cloudflared tunnel' | head -1)
|
|
echo " PID=$pid"
|
|
[ -n "$pid" ] && tr '\0' ' ' < /proc/$pid/cmdline 2>/dev/null | sed 's/^/ /'
|
|
echo
|
|
|
|
echo "════════ 8. cloudflared 自己测一次回源 ════════"
|
|
# cloudflared 有 diagnose 子命令,能报出配置和连通性
|
|
cloudflared tunnel --config /root/.cloudflared/config.yml ingress validate 2>&1 | tail -12 | sed 's/^/ /'
|