Files
ykxmz/_build/diag_tunnel_log.py
xmz7891 8dc47d0f48 2.1.2:隧道稳定性加固(继续修「网站还是容易挂」)
2.1.1 修掉了 nettune 死锁之后,公网上到 200,但**过一阵又 530**。
这次抓到的是隧道自己:

cloudflared 的 precheck 输出(tunnel.log):

    | UDP Connectivity  region1.v2.argotunnel.com  FAIL  QUIC connection failed                      |
    | TCP Connectivity  region1.v2.argotunnel.com  FAIL  HTTP/2 connection is blocked or unreachable |
    | Cloudflare API    api.cloudflare.com:443     PASS  API is reachable                            |
    | ERROR: Allow outbound QUIC traffic on port 7844 or use HTTP2.                                  |

也就是 **443 通、7844 不通**,而且是**间歇性**的(过几分钟自己又好了,
然后再次断)。Cloudflare 隧道的边缘连接走 7844(QUIC 走 UDP 7844、
HTTP/2 走 TCP 7844)。这条线路对它是间歇性阻断 —— 属于运营商那一侧,
设备改不了,但可以让 cloudflared 自己去适应。

== 两个改动 ==

1. **协议从写死改成 auto**
       lanremote-tunnel      --protocol quic    -> --protocol auto
       lanremote-tunnel-h2   --protocol http2   -> --protocol auto
   原来两条实例各赌一个协议:那一刻 7844 的 UDP 和 TCP 都不通就一起死,
   没有退路(实测连接数掉到 1/0、公网 530)。改成 auto 之后
   cloudflared 自己在 QUIC / HTTP/2 之间挑当前能通的那条,
   10 条连接全都有自适应能力。

2. **--retries 5 -> 1000000**
   原来失败 5 次就退出、靠 systemd Restart=always 拉起来,
   每次退出到重启之间网站都是断的。而这条线路的抖动是分钟级的 ——
   实测隧道每 3~10 分钟就被重启一次(19:37 / 19:40 / 19:43 / 19:50 / 19:52),
   公网跟着一起断。拉大之后抖动期间连接自己恢复,整条隧道不退出。

3. 顺手加日志轮转(tunnel.log 已经 2.98 MB,这台机器硬盘不大)。

== 实测 ==

    改前:连接数 1/0,公网 530
    改后:连接数 7+2(接近满配 10),公网连测 5 次全部 200

== 同步 ==

relay/deploy.sh 里的 MAIN_PROTO / ALT_PROTO 也改成 auto、
TUNNEL_BASE 的 --retries 也拉到 1000000,新机器装出来就是加固过的。

全量回归 46 个阶段全部通过。
2026-10-08 20:04:35 +08:00

67 lines
2.0 KiB
Python

# -*- coding: utf-8 -*-
r'''看隧道为什么反复掉(公网 530 的真因)。
已知:
nettune 死锁已修(SubState=exited,不再卡)
但隧道每 3~10 分钟被重启一次(部分是我加的预案在救、部分是它自己掉)
公网 530
要查的是 tunnel.log 里 cloudflared 到底在报什么。
'''
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "_build"))
from devssh import run # noqa: E402
REMOTE = r'''
LOG=/root/lanremote-relay/tunnel.log
H2LOG=/root/lanremote-relay/tunnel-h2.log
echo "════ 1. tunnel.log 里的错误行(最近 40 条)════"
grep -iE 'error|fail|warn|timeout|retry|refused|EOF|unregister|connection' "$LOG" 2>/dev/null | tail -40 | sed 's/^/ /'
echo
echo "════ 2. tunnel.log 最后 25 行(原样)════"
tail -25 "$LOG" 2>/dev/null | sed 's/^/ /'
echo
echo "════ 3. h2 那份的日志 ════"
tail -15 "$H2LOG" 2>/dev/null | sed 's/^/ /'
echo
echo "════ 4. 两份日志多大(写爆了会拖慢小机器)════"
ls -la "$LOG" "$H2LOG" 2>/dev/null | sed 's/^/ /'
echo
echo "════ 5. cloudflared 版本 + 配置 ════"
/usr/local/bin/cloudflared --version 2>&1 | sed 's/^/ /'
echo " --- config.yml ---"
cat /root/.cloudflared/config.yml 2>/dev/null | sed 's/^/ /'
echo
echo "════ 6. 现在两条隧道的连接数 ════"
for p in 20241 20242; do
n=$(curl -s --max-time 5 "http://127.0.0.1:$p/metrics" 2>/dev/null | grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}' | head -1)
echo " $p -> ${n:-拿不到}"
done
echo
echo "════ 7. 公网现在通吗 ════"
echo " $(curl -s -o /dev/null -w '%{http_code}' --max-time 15 https://relay.xxmxxs.top/v1/health)"
'''
def main() -> int:
out = run(REMOTE, timeout=300)
text = out[1] if isinstance(out, tuple) else str(out)
print(text)
return 0
if __name__ == "__main__":
sys.exit(main())