Files
xmz7891 8c4ee6df08 修真凶:4G 链路静默断连导致隧道"假活"(用户撞上 Error 1033)
现象:用户早上打开 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 台
2026-10-07 09:15:27 +08:00

46 lines
2.3 KiB
Bash

#!/bin/bash
# 发一个公网请求,紧跟着看隧道日志处理了什么 —— 定位 502 到底出在哪一段
set -u
RELAY_DIR=/root/lanremote-relay
echo "════════ 1. 打标记,好区分新旧日志 ════════"
echo "---- PROBE $(date -u +%H:%M:%S) ----" >> "$RELAY_DIR/tunnel.log"
before=$(wc -l < "$RELAY_DIR/tunnel.log")
echo " 日志当前 $before 行"
echo
echo "════════ 2. 从设备自己请求公网(发夹回路,但能看出链路上通不通)════════"
curl -s -o /tmp/pub.out -w ' HTTP %{http_code} 用时 %{time_total}s 大小 %{size_download}\n' \
--max-time 30 -H 'User-Agent: LanRemote/1.4.0' https://relay.xxmxxs.top/v1/health
echo " 响应头 5 行:"
head -5 /tmp/pub.out | sed 's/^/ /'
echo
echo "════════ 3. 请求短路径(首页,只有 15KB)════════"
curl -s -o /tmp/pub2.out -w ' HTTP %{http_code} 用时 %{time_total}s 大小 %{size_download}\n' \
--max-time 30 -H 'User-Agent: LanRemote/1.4.0' https://relay.xxmxxs.top/
head -3 /tmp/pub2.out | sed 's/^/ /'
echo
echo "════════ 4. 请求一个极小的路径 ════════"
curl -s -o /dev/null -w ' /favicon.ico HTTP %{http_code} 用时 %{time_total}s 大小 %{size_download}\n' \
--max-time 30 -H 'User-Agent: LanRemote/1.4.0' https://relay.xxmxxs.top/favicon.ico
echo
echo "════════ 5. 这几条请求之后,隧道日志新增了什么 ════════"
after=$(wc -l < "$RELAY_DIR/tunnel.log")
echo " 新增 $((after - before)) 行:"
tail -n +$((before + 1)) "$RELAY_DIR/tunnel.log" | tail -30 | 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_(total_requests|request_errors|response_by_code)' | sed 's/^/ /'
echo
echo "════════ 7. relay 自己的日志(不是 journal,是它可能写的文件)════════"
ls -la "$RELAY_DIR"/*.log 2>/dev/null | sed 's/^/ /'
echo " relay 最近通过隧道服务的请求(如果有访问日志):"
journalctl -u lanremote-relay --since '2 minutes ago' --no-pager 2>/dev/null | tail -10 | sed 's/^/ /'