#!/bin/bash # 长时间对照:http2+4(基线) vs quic+6(候选)。 # # 为什么要跑长的: # 短测(20 次)看不出稳定性。而且历史上出过一次"QUIC 可用率 48%", # 和这次短测的 20/20 矛盾 —— 必须用足够长的样本、并且**同时**记录 # 连接数波动和重连次数,才能判断到底是协议问题还是当时的网络问题。 # # 每轮 5 分钟,每 3 秒一次请求(约 100 个样本),记录: # 成功率 / 中位 / P90 / 最大 / 连接数最低值 / 连接的落点 set -u URL=https://relay.xxmxxs.top/v1/health UA='LanRemote/1.8.0' SVC=/etc/systemd/system/lanremote-tunnel.service BACKUP=/root/lanremote-tunnel.service.bak.long.$(date +%s) cp -a "$SVC" "$BACKUP" DURATION=300 # 每轮 5 分钟 INTERVAL=3 # 每 3 秒一次 set_params() { local proto="$1" conns="$2" if grep -q -- '--protocol' "$SVC"; then sed -i "s/--protocol [a-z0-9]*/--protocol $proto/" "$SVC" else sed -i "s|\(ExecStart=.*cloudflared tunnel\)|\1 --protocol $proto|" "$SVC" fi if grep -q -- '--ha-connections' "$SVC"; then sed -i "s/--ha-connections [0-9]*/--ha-connections $conns/" "$SVC" else sed -i "s|\(ExecStart=.*cloudflared tunnel\)|\1 --ha-connections $conns|" "$SVC" fi systemctl daemon-reload systemctl restart lanremote-tunnel } wait_ready() { local want="$1" for i in $(seq 1 30); do sleep 5 n=$(curl -s --max-time 4 http://127.0.0.1:20241/metrics 2>/dev/null \ | grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}') if [ "${n:-0}" -ge "$want" ]; then return 0 fi done return 1 } measure() { local label="$1" local ok=0 fail=0 times=() minconn=99 reconnects=0 local start=$(date +%s) local logmark=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0) echo " ── $label:跑 ${DURATION} 秒,每 ${INTERVAL} 秒一次 ──" while [ $(( $(date +%s) - start )) -lt "$DURATION" ]; do out=$(curl -s -o /dev/null -w '%{http_code} %{time_total}' --max-time 30 -H "User-Agent: $UA" "$URL") code=$(echo "$out" | awk '{print $1}') ms=$(echo "$out" | awk '{printf "%d", $2*1000}') if [ "$code" = "200" ]; then ok=$((ok+1)); times+=("$ms") else fail=$((fail+1)) fi n=$(curl -s --max-time 3 http://127.0.0.1:20241/metrics 2>/dev/null \ | grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}') [ -n "${n:-}" ] && [ "$n" -lt "$minconn" ] && minconn="$n" sleep "$INTERVAL" done # 这一轮新注册了多少次(= 重连次数) nowmark=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0) reconnects=$(tail -n +$((logmark+1)) /root/lanremote-relay/tunnel.log 2>/dev/null \ | grep -c 'Registered tunnel connection' || echo 0) total=$((ok+fail)) pct=0; [ "$total" -gt 0 ] && pct=$((ok * 100 / total)) stats=$(printf '%s\n' "${times[@]:-0}" | sort -n | awk '{a[NR]=$1} END { if (NR==0) { print "无数据"; exit } printf "中位 %d P90 %d 最大 %d", a[int(NR/2)+1], a[int(NR*0.9)+1], a[NR]}') echo " == 结果: $ok/$total = ${pct}% $stats ms" echo " 连接数最低 $minconn 本轮重连 $reconnects 次" echo "$label|$ok|$total|$pct|$stats|$minconn|$reconnects" >> /tmp/longab.txt echo } rm -f /tmp/longab.txt echo "════════ 第一轮:http2 + 4(基线)════════" set_params http2 4 wait_ready 4 && echo " 连接就绪" || echo " ! 连接没建齐,继续测" sleep 10 measure "http2+4" echo "════════ 第二轮:quic + 6(候选)════════" set_params quic 6 wait_ready 6 && echo " 连接就绪" || echo " ! 连接没建齐,继续测" sleep 10 measure "quic+6" echo "════════ 汇总 ════════" printf " %-12s %-14s %-10s %-22s %-10s %s\n" "配置" "成功" "可用率" "延迟" "连接最低" "重连" while IFS='|' read -r label ok total pct stats minconn reconnects; do printf " %-12s %-14s %-10s %-22s %-10s %s\n" "$label" "$ok/$total" "${pct}%" "$stats" "$minconn" "$reconnects" done < /tmp/longab.txt echo echo "════════ 按结果决定是否改配置 ════════" BASE_PCT=$(grep '^http2+4' /tmp/longab.txt | cut -d'|' -f4) QUIC_PCT=$(grep '^quic+6' /tmp/longab.txt | cut -d'|' -f4) if [ "${QUIC_PCT:-0}" -ge "${BASE_PCT:-0}" ] && [ "${QUIC_PCT:-0}" -ge 90 ]; then echo " → quic+6 可用率 ${QUIC_PCT}% >= 基线 ${BASE_PCT}%,保留 quic+6" grep -oE '\-\-protocol [a-z0-9]+|--ha-connections [0-9]+' "$SVC" | sed 's/^/ /' else echo " → quic+6 可用率 ${QUIC_PCT}% 不如基线 ${BASE_PCT}%,回滚" cp -a "$BACKUP" "$SVC" systemctl daemon-reload systemctl restart lanremote-tunnel sleep 20 grep -oE '\-\-protocol [a-z0-9]+|--ha-connections [0-9]+' "$SVC" | sed 's/^/ /' fi echo echo " 当前连接数: $(curl -s --max-time 5 http://127.0.0.1:20241/metrics 2>/dev/null | grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}')" echo " 备份: $BACKUP"