mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 19:30:42 +00:00
实测单个请求有 2~4% 的偶发失败(4G 丢包打在一条隧道连接上, 或者那条连接正在重连)。原逻辑是一失败就 online = false, 于是界面上会闪一下已断开 —— 用户点按钮时正好撞上那一闪, 看起来就像又连不上了。 而链路其实 1.5~15 秒就自己恢复(客户端本来就有退避重试)。 改成连续失败 3 次才判离线(手表至少 4.5 秒、电脑至少 6 秒): * 单次抖动完全不影响界面 * 真的断了仍然如实显示 这不是掩盖问题,而是把是否可用的判断从一次采样改成连续采样 —— 单点采样在有丢包的链路上噪声太大。 两边同步改: android .../RelayTransport.java failStreak + OFFLINE_AFTER windows/lanremote/relay.py _fail_streak + OFFLINE_AFTER 顺带记录 PC 端基准(真实用户视角,之前都是在设备上量的, 那等于把设备 4G 算了两遍): 公网可用率 98% 耗时 中位 911 P90 1889 P99 23868 ms 长轮询 5/6 耗时 60.8~62.1 秒 对比设备端(中位 1344 / P90 2563)—— 用户实际体验比设备端量出来的好。
134 lines
5.7 KiB
Bash
134 lines
5.7 KiB
Bash
#!/bin/bash
|
||
# 1) 把 MTU 1400 固化下来(重启也在)
|
||
# 2) 在 MTU 1400 下对照 quic+6 / quic+8 / quic+10
|
||
#
|
||
# 为什么要固化 MTU:
|
||
# QUIC 走 UDP,**我们那条 --set-mss 1400 的 iptables 规则只管 TCP**。
|
||
# 实测把 wlan0 MTU 从 1500 降到 1400 之后:
|
||
# QUIC 建齐 6 条连接的时间 28 秒 -> 13 秒
|
||
# dial 失败次数 2 -> 1
|
||
# 原因:UDP 丢包不会回 ICMP,QUIC 发了超出路径 MTU 的包只能等超时。
|
||
# 把接口 MTU 压到 1400,QUIC 的包就都在安全范围内。
|
||
#
|
||
# 为什么还要试更多连接:
|
||
# 已经看到 http2+8 建齐只要 12 秒且 0 失败(QUIC+6 是 28 秒/2 次失败)。
|
||
# 连接多 = 单条掉线影响小。但 QUIC 的连接建立更贵,得实测平衡点。
|
||
set -u
|
||
|
||
BASE=https://relay.xxmxxs.top
|
||
UA='LanRemote/1.8.2'
|
||
SVC=/etc/systemd/system/lanremote-tunnel.service
|
||
NETTUNE=/etc/systemd/system/lanremote-nettune.service
|
||
BACKUP=/root/tunnel.bak.v4.$(date +%s)
|
||
cp -a "$SVC" "$BACKUP"
|
||
N=60
|
||
MTU=1400
|
||
MSS=1360
|
||
|
||
echo "════════ 1. 固化 MTU(写进 net-tune 服务)════════"
|
||
echo " 现在的 net-tune 服务:"
|
||
systemctl cat lanremote-nettune 2>/dev/null | grep -E 'ExecStart' | sed 's/^/ /'
|
||
|
||
# 把 MTU 设置追加进去(幂等:已有的先删掉)
|
||
cp -a "$NETTUNE" "${NETTUNE}.bak.$(date +%s)" 2>/dev/null || true
|
||
python3 - <<'PYEOF'
|
||
from pathlib import Path
|
||
p = Path("/etc/systemd/system/lanremote-nettune.service")
|
||
if not p.is_file():
|
||
print(" ! net-tune 服务不存在,跳过")
|
||
raise SystemExit(0)
|
||
text = p.read_text(encoding="utf-8")
|
||
# 去掉旧的 MTU/MSS 行
|
||
lines = [l for l in text.splitlines()
|
||
if "ip link set wlan0 mtu" not in l and "--set-mss" not in l]
|
||
out = []
|
||
for line in lines:
|
||
out.append(line)
|
||
# 在每个 ExecStart 之后补上 MTU 设置
|
||
if line.strip().startswith("ExecStart="):
|
||
out.append("ExecStart=/sbin/ip link set wlan0 mtu 1400")
|
||
out.append("ExecStart=/sbin/iptables -t mangle -C OUTPUT -p tcp "
|
||
"--tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360 || "
|
||
"/sbin/iptables -t mangle -A OUTPUT -p tcp "
|
||
"--tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360")
|
||
p.write_text("\n".join(out) + "\n", encoding="utf-8")
|
||
print(" 已写入 MTU 1400 + MSS 1360")
|
||
PYEOF
|
||
|
||
systemctl daemon-reload
|
||
echo " 立即执行一次:"
|
||
ip link set wlan0 mtu $MTU && echo " wlan0 MTU -> $(cat /sys/class/net/wlan0/mtu)"
|
||
iptables -t mangle -C OUTPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss $MSS 2>/dev/null \
|
||
|| iptables -t mangle -A OUTPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss $MSS
|
||
echo " MSS 规则: $(iptables -t mangle -S OUTPUT | grep TCPMSS | head -1)"
|
||
echo " net-tune 现在的内容:"
|
||
systemctl cat lanremote-nettune 2>/dev/null | grep ExecStart | sed 's/^/ /'
|
||
echo " 服务状态: $(systemctl is-enabled lanremote-nettune 2>/dev/null) / $(systemctl is-active lanremote-nettune 2>/dev/null)"
|
||
|
||
wait_conns() {
|
||
local want="$1" limit="$2" t0 t1 n
|
||
t0=$(date +%s)
|
||
while true; do
|
||
n=$(curl -s --max-time 4 http://127.0.0.1:20241/metrics 2>/dev/null \
|
||
| grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}')
|
||
n=${n:-0}
|
||
t1=$(date +%s)
|
||
[ "$n" -ge "$want" ] || [ $((t1 - t0)) -ge "$limit" ] && { echo "$n $((t1 - t0))"; return; }
|
||
sleep 3
|
||
done
|
||
}
|
||
|
||
run_group() {
|
||
local conns="$1"
|
||
echo "════════ quic + $conns (MTU $MTU)════════"
|
||
cp -a "$BACKUP" "$SVC"
|
||
sed -i "s/--protocol [a-z0-9]*/--protocol quic/" "$SVC"
|
||
sed -i "s/--ha-connections [0-9]*/--ha-connections $conns/" "$SVC"
|
||
systemctl daemon-reload
|
||
local mark; mark=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0)
|
||
systemctl restart lanremote-tunnel
|
||
local res; res=$(wait_conns "$conns" 150)
|
||
local n s
|
||
n=$(echo "$res" | awk '{print $1}'); s=$(echo "$res" | awk '{print $2}')
|
||
local df; df=$(tail -n +$((mark+1)) /root/lanremote-relay/tunnel.log 2>/dev/null | grep -c 'Failed to dial' || echo 0)
|
||
echo " 建齐 $n/$conns,用 ${s} 秒,dial 失败 ${df} 次"
|
||
|
||
local ok=0 times=()
|
||
for i in $(seq 1 "$N"); do
|
||
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}')
|
||
[ "$c" = "200" ] && { ok=$((ok+1)); times+=("$ms"); }
|
||
done
|
||
local pct=$((ok * 100 / N))
|
||
local stats="无数据"
|
||
[ "${#times[@]}" -gt 0 ] && stats=$(printf '%s\n' "${times[@]}" | sort -n | awk '{a[NR]=$1} END {
|
||
printf "中位 %d P90 %d P99 %d 最大 %d", a[int(NR/2)+1], a[int(NR*0.9)+1], a[int(NR*0.99)+1], a[NR]}')
|
||
printf " 可用率 %d%% (%d/%d) %s ms\n" "$pct" "$ok" "$N" "$stats"
|
||
echo "quic+$conns|$n|$s|$df|$pct|$stats" >> /tmp/v4.txt
|
||
echo
|
||
}
|
||
|
||
rm -f /tmp/v4.txt
|
||
run_group 6
|
||
run_group 8
|
||
run_group 10
|
||
|
||
echo "════════ 汇总 ════════"
|
||
printf " %-10s %-14s %-10s %-8s %s\n" "配置" "建齐/耗时" "dial失败" "可用率" "延迟"
|
||
while IFS='|' read -r label n s df pct stats; do
|
||
printf " %-10s %-14s %-10s %-8s %s\n" "$label" "${n}条 ${s}s" "$df" "${pct}%" "$stats"
|
||
done < /tmp/v4.txt
|
||
|
||
echo
|
||
BESTN=$(sort -t'|' -k5 -rn /tmp/v4.txt | head -1 | sed 's/quic+//' | cut -d'|' -f1)
|
||
echo " → 采用 quic + $BESTN"
|
||
cp -a "$BACKUP" "$SVC"
|
||
sed -i "s/--protocol [a-z0-9]*/--protocol quic/" "$SVC"
|
||
sed -i "s/--ha-connections [0-9]*/--ha-connections $BESTN/" "$SVC"
|
||
systemctl daemon-reload
|
||
systemctl restart lanremote-tunnel
|
||
sleep 5
|
||
echo " 最终参数: $(grep -oE '\-\-protocol [a-z0-9]+|--ha-connections [0-9]+' "$SVC" | tr '\n' ' ')"
|
||
echo " MTU: $(cat /sys/class/net/wlan0/mtu)"
|
||
echo " 备份: $BACKUP"
|