#!/bin/bash # 双协议隧道的长时稳定性测量。 # # 和之前的 longstab.sh 区别:现在有**两个** cloudflared 实例, # 只有先起的那个能绑上 20241 metrics 端口,所以不能只看 metrics # 的连接数 —— 要分别从两个日志里数"当前活跃连接"。 # # 每轮记录: # * QUIC 实例 / HTTP2 实例 各自最近注册的连接数 # * 公网可用率 # * 掉线、dial 失败、530/502 事件 set -u BASE=https://relay.xxmxxs.top UA='LanRemote/1.8.2' MINUTES=${1:-30} LABEL=${2:-dual} ROUNDS=$((MINUTES * 6)) OUT=/root/longstab_${LABEL}.txt MARK_Q=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0) MARK_H=$(wc -l < /root/lanremote-relay/tunnel-h2.log 2>/dev/null || echo 0) echo "════════ 双协议隧道长测 · $LABEL · ${MINUTES} 分钟 ════════" | tee "$OUT" echo " QUIC: $(grep -oE '\-\-protocol [a-z0-9]+|--ha-connections [0-9]+' /etc/systemd/system/lanremote-tunnel.service | tr '\n' ' ')" | tee -a "$OUT" echo " HTTP2: $(grep -oE '\-\-protocol [a-z0-9]+|--ha-connections [0-9]+' /etc/systemd/system/lanremote-tunnel-h2.service | tr '\n' ' ')" | tee -a "$OUT" echo " MTU: $(cat /sys/class/net/wlan0/mtu)" | tee -a "$OUT" echo " 开始: $(date '+%H:%M:%S')" | tee -a "$OUT" okA=0; totA=0; timesA=() zeroQ=0; zeroH=0; low=0 declare -a events for r in $(seq 1 "$ROUNDS"); do # 各自实例"最近 500 行里,注册后又没掉线"的净连接数 —— 用最近事件近似 nq=$(tail -200 /root/lanremote-relay/tunnel.log 2>/dev/null \ | grep -c 'Registered tunnel connection') nh=$(tail -200 /root/lanremote-relay/tunnel-h2.log 2>/dev/null \ | grep -c 'Registered tunnel connection') # 每 3 轮(30 秒)打一次公网 if [ $((r % 3)) -eq 0 ]; then out=$(curl -s -o /dev/null -w '%{http_code} %{time_total}' --max-time 25 \ -H "User-Agent: $UA" "$BASE/v1/health") c=$(echo "$out" | awk '{print $1}') ms=$(echo "$out" | awk '{printf "%d", $2*1000}') totA=$((totA + 1)) if [ "$c" = "200" ]; then okA=$((okA + 1)); timesA+=("$ms") else events+=("[$(date '+%H:%M:%S')] HTTP $c") printf " [%s] ✗ HTTP %s (Q=%s H=%s)\n" "$(date '+%H:%M:%S')" "$c" "$nq" "$nh" | tee -a "$OUT" fi fi sleep 10 done echo | tee -a "$OUT" echo "════════ 结果 ════════" | tee -a "$OUT" pct=$((okA * 100 / (totA > 0 ? totA : 1))) echo " 公网可用率: $okA/$totA = ${pct}%" | tee -a "$OUT" if [ "${#timesA[@]}" -gt 0 ]; then printf '%s\n' "${timesA[@]}" | sort -n | awk '{ a[NR]=$1 } END { printf " 耗时: 最小 %d 中位 %d P90 %d P99 %d 最大 %d ms\n", a[1], a[int(NR/2)+1], a[int(NR*0.9)+1], a[int(NR*0.99)+1], a[NR] }' | tee -a "$OUT" fi echo | tee -a "$OUT" echo " QUIC 实例事件:" | tee -a "$OUT" for kw in 'Registered tunnel connection' 'Lost connection' 'Failed to dial' 'no recent network activity'; do c=$(tail -n +$((MARK_Q+1)) /root/lanremote-relay/tunnel.log 2>/dev/null | grep -c "$kw" || echo 0) printf " %-34s %s 次\n" "$kw" "$c" | tee -a "$OUT" done echo " HTTP/2 实例事件:" | tee -a "$OUT" for kw in 'Registered tunnel connection' 'Lost connection' 'Failed to dial' 'i/o timeout'; do c=$(tail -n +$((MARK_H+1)) /root/lanremote-relay/tunnel-h2.log 2>/dev/null | grep -c "$kw" || echo 0) printf " %-34s %s 次\n" "$kw" "$c" | tee -a "$OUT" done echo | tee -a "$OUT" echo " HTTP 失败时刻:" | tee -a "$OUT" if [ "${#events[@]}" -gt 0 ]; then printf ' %s\n' "${events[@]}" | tee -a "$OUT" else echo " 一次都没有" | tee -a "$OUT" fi echo | tee -a "$OUT" echo " 存档: $OUT" | tee -a "$OUT"