Files
ykxmz/_build/test_poll_reliability.sh
2026-10-07 14:24:06 +08:00

99 lines
4.2 KiB
Bash

#!/bin/bash
# 长轮询可靠性长测:连打 20 次(每次挂 60 秒,共约 20 分钟)。
#
# 为什么单独测这个:
# 上一轮 A/B 里 http2+4 是 7/8(有 1 次 000 失败)。
# 12.5% 的失败率对"手表点一下要能用"来说太高了,必须查清:
# * 是偶发抖动?
# * 还是每 8 次就必然挂一次(那就跟隧道重连周期有关)?
#
# 顺带修掉上轮脚本的 bug:探针设备用了同一个配对码,
# 第二次注册被"一个码只能一台设备"规则拒掉,token 拿到空的。
# 这里每次用**唯一的新码**。
set -u
PUB=https://relay.xxmxxs.top
LOCAL=http://127.0.0.1:8080
UA='LanRemote/1.8.0'
ROUNDS=${1:-20}
echo "════════ 注册探针(用唯一配对码)════════"
STAMP=$(date +%s)
DEV="relprobe-${STAMP}"
# 6 位数字,取自时间戳后 6 位,避免和上一轮撞
CODE=$(printf "%06d" $(( STAMP % 1000000 )))
REG=$(curl -s --max-time 30 -X POST "$PUB/v1/agent/register" \
-H 'Content-Type: application/json' -H "User-Agent: $UA" \
-d "{\"deviceId\":\"$DEV\",\"code\":\"$CODE\",\"name\":\"relprobe\",\"version\":\"1.8.0\"}")
echo " 注册响应: $(echo "$REG" | head -c 160)"
TOKEN=$(echo "$REG" | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))" 2>/dev/null)
if [ -z "$TOKEN" ]; then
echo " [失败] 没拿到 token,注册被拒了"
exit 1
fi
echo " token ${#TOKEN} 字符,配对码 $CODE"
echo
echo "════════ 隧道现状 ════════"
echo " 参数: $(grep -oE '\-\-protocol [a-z0-9]+|--ha-connections [0-9]+' /etc/systemd/system/lanremote-tunnel.service | tr '\n' ' ')"
echo " 连接: $(curl -s --max-time 5 http://127.0.0.1:20241/metrics 2>/dev/null | grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}')"
curl -s --max-time 5 http://127.0.0.1:20241/metrics 2>/dev/null \
| grep 'server_locations.*} 1' | sed 's/^/ /'
echo
echo "════════ 开始连打 $ROUNDS 次长轮询 ════════"
ok=0; fail=0; times=(); fails=""
LOGMARK=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0)
for i in $(seq 1 "$ROUNDS"); do
out=$(curl -s -o /dev/null -w '%{http_code} %{time_total}' --max-time 100 \
-X POST "$PUB/v1/agent/poll" -H "X-Token: $TOKEN" -H "User-Agent: $UA")
code=$(echo "$out" | awk '{print $1}')
ms=$(echo "$out" | awk '{printf "%d", $2*1000}')
if [ "$code" = "200" ]; then
ok=$((ok+1)); times+=("$ms")
printf " %2d: 200 %6dms\n" "$i" "$ms"
else
fail=$((fail+1)); fails="$fails ${i}:${code}"
printf " %2d: %-4s **失败**\n" "$i" "$code"
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}')
[ "$code" != "200" ] && printf " 失败时连接数: %s\n" "${n:-?}"
done
echo
echo "════════ 结果 ════════"
total=$((ok+fail))
echo " 成功 $ok/$total = $((ok * 100 / total))%"
echo " 失败:$fails"
if [ "${#times[@]}" -gt 0 ]; then
printf '%s\n' "${times[@]}" | sort -n | awk '{
a[NR]=$1
} END {
printf " 耗时: 最小 %d 中位 %d P90 %d 最大 %d ms\n",
a[1], a[int(NR/2)+1], a[int(NR*0.9)+1], a[NR]
}'
fi
echo
echo " 这一轮的隧道事件(重连/超时):"
NOWMARK=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0)
tail -n +$((LOGMARK+1)) /root/lanremote-relay/tunnel.log 2>/dev/null \
| grep -cE 'Registered tunnel connection' \
| sed 's/^/ 重连次数: /'
tail -n +$((LOGMARK+1)) /root/lanremote-relay/tunnel.log 2>/dev/null \
| grep -E 'Lost connection|i/o timeout|context deadline' | tail -6 | sed 's/^/ /'
echo
echo " watchdog 最近:"
tail -6 /root/lanremote-relay/watchdog.log 2>/dev/null | sed 's/^/ /'
echo
echo "════════ 清掉探针 ════════"
KEY=$(cat /root/lanremote-relay/data/admin_key.txt 2>/dev/null)
curl -s --max-time 20 -X POST "$LOCAL/v1/admin/delete" -H "X-Admin: $KEY" \
-H 'Content-Type: application/json' -d "{\"deviceId\":\"$DEV\"}" | head -c 100
echo