Files
ykxmz/_build/rp_ab_long.sh
T

149 lines
6.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 长窗口配比对照用的测量脚本(支持 A/B 两组,各跑 >=40 分钟)
#
# 与 rp_long2h.sh 的区别:
# * 时长可指定(分钟)
# * **额外采样内存和 CPU**(Lead 问 h2 提到 4 条对 460MB 设备有无影响)
# * 输出文件名带标签,方便 A/B 分开比对
#
# 用法: bash rp_ab_long.sh <标签> <分钟数>
set -u
LABEL=${1:-A}
MINS=${2:-45}
BASE=https://relay.xxmxxs.top
UA='LanRemote/1.8.2'
DUR=$((MINS * 60))
HEALTH_EVERY=15
CONN_EVERY=60
RES_EVERY=60
H=/root/ab_${LABEL}_health.tsv
C=/root/ab_${LABEL}_conns.tsv
R=/root/ab_${LABEL}_res.tsv
S=/root/ab_${LABEL}_summary.txt
rm -f "$H" "$C" "$R" "$S"
conns_of() {
curl -s --max-time 4 "http://127.0.0.1:$1/metrics" 2>/dev/null \
| grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}'
}
M0=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0)
H0=$(wc -l < /root/lanremote-relay/tunnel-h2.log 2>/dev/null || echo 0)
T0=$(date +%s)
NEXT_CONN=$T0
NEXT_RES=$T0
echo " 开始 $LABEL: $(date '+%H:%M:%S') 持续 ${MINS} 分钟"
while true; do
NOW=$(date +%s)
[ $((NOW - T0)) -ge "$DUR" ] && break
out=$(curl -s -o /dev/null -w '%{http_code} %{time_total}' --max-time 25 \
-H "User-Agent: $UA" "$BASE/v1/health")
code=$(echo "$out" | awk '{print $1}')
ms=$(echo "$out" | awk '{printf "%d", $2*1000}')
echo "$(date '+%Y-%m-%d %H:%M:%S') $code $ms" >> "$H"
if [ "$NOW" -ge "$NEXT_CONN" ]; then
a=$(conns_of 20241); b=$(conns_of 20242)
echo "$(date '+%Y-%m-%d %H:%M:%S') ${a:-X} ${b:-X}" >> "$C"
NEXT_CONN=$((NOW + CONN_EVERY))
fi
if [ "$NOW" -ge "$NEXT_RES" ]; then
# 两个 cloudflared 各占多少常驻内存 + CPU
qm=0; hm=0; qc=0; hc=0
for p in $(pgrep cloudflared); do
proto=$(tr '\0' ' ' < /proc/$p/cmdline 2>/dev/null | grep -oE '\-\-protocol [a-z0-9]+' | awk '{print $2}')
rss=$(awk '/VmRSS/{print $2}' /proc/$p/status 2>/dev/null)
cpu=$(ps -o %cpu= -p $p 2>/dev/null | tr -d ' ')
if [ "$proto" = "quic" ]; then qm=${rss:-0}; qc=${cpu:-0};
elif [ "$proto" = "http2" ]; then hm=${rss:-0}; hc=${cpu:-0}; fi
done
total=$(free -m | awk '/Mem:/{print $3}')
avail=$(free -m | awk '/Mem:/{print $7}')
load=$(awk '{print $1}' /proc/loadavg)
echo "$(date '+%Y-%m-%d %H:%M:%S') ${qm} ${hm} ${qc} ${hc} ${total} ${avail} ${load}" >> "$R"
NEXT_RES=$((NOW + RES_EVERY))
fi
sleep "$HEALTH_EVERY"
done
M1=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0)
H1=$(wc -l < /root/lanremote-relay/tunnel-h2.log 2>/dev/null || echo 0)
{
echo "════════════════════════════════════════════════════════"
echo " $LABEL 组 · ${MINS} 分钟 · $(date '+%Y-%m-%d %H:%M:%S')"
echo "════════════════════════════════════════════════════════"
echo
echo "── 配置 ──"
for svc in lanremote-tunnel lanremote-tunnel-h2; do
echo " $svc: $(systemctl cat $svc 2>/dev/null | grep -oE '\-\-protocol [a-z0-9]+|\-\-ha-connections [0-9]+' | tr '\n' ' ')"
done
echo
echo "── 公网可用率 ──"
n=$(grep -c . "$H" 2>/dev/null || echo 0)
ok=$(awk -F'\t' '$2=="200"' "$H" 2>/dev/null | wc -l)
echo " $ok/$n = $(awk -v a="$ok" -v b="$n" 'BEGIN{if(b>0)printf "%.2f", a*100/b; else print 0}')%"
echo " 状态码: $(awk -F'\t' '{print $2}' "$H" 2>/dev/null | sort | uniq -c | tr '\n' ' ')"
awk -F'\t' '$2=="200"{print $3}' "$H" 2>/dev/null | sort -n | awk '
{a[NR]=$1}
END{if(NR==0){print " 无数据"; exit}
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]}'
echo " 失败时刻:"
awk -F'\t' '$2!="200"{print " " $1 " 码=" $2 " " $3 "ms"}' "$H" 2>/dev/null
echo
echo "── 连接数 ──"
awk -F'\t' 'NR>1 && $2 ~ /^[0-9]+$/ && $3 ~ /^[0-9]+$/ {
t=$2+$3; cnt[t]++
if (t<=3) low++
if (t<min || min=="") min=t
if (t>max) max=t
} END {
printf " 最小 %d 最大 %d 平均 %.2f\n", min, max, 0
printf " 总连接数<=3 的采样: %d 次(占 %.1f%%)\n", low+0, (low+0)*100/NR
}' "$C" 2>/dev/null
echo " 分布: $(awk -F'\t' 'NR>1 && $2 ~ /^[0-9]+$/ && $3 ~ /^[0-9]+$/ {print $2+$3}' "$C" | sort -n | uniq -c | tr '\n' ' ')"
echo
echo "── 内存 / CPU ──"
awk -F'\t' 'NR>1 {
if ($2+0>qm) qm=$2
if ($3+0>hm) hm=$3
if ($4+0>qc) qc=$4
if ($5+0>hc) hc=$5
if ($6+0>tm) tm=$6
if (minav=="" || $7+0<minav) minav=$7
if ($8+0>ld) ld=$8
} END {
printf " QUIC 实例常驻内存峰值: %.1f MB\n", qm/1024
printf " HTTP/2 实例常驻内存峰值: %.1f MB\n", hm/1024
printf " 两者合计: %.1f MB\n", (qm+hm)/1024
printf " CPU 峰值: quic %.1f%% http2 %.1f%%\n", qc, hc
printf " 设备已用内存峰值: %d MB 最少可用: %d MB\n", tm, minav
printf " 负载峰值: %.2f\n", ld
}' "$R" 2>/dev/null
echo
echo "── 隧道事件(本轮增量)──"
printf " QUIC 注册 %s 失败 %s 掉线 %s\n" \
"$(tail -n +$((M0+1)) /root/lanremote-relay/tunnel.log 2>/dev/null | grep -c 'Registered tunnel connection')" \
"$(tail -n +$((M0+1)) /root/lanremote-relay/tunnel.log 2>/dev/null | grep -c 'Failed to dial')" \
"$(tail -n +$((M0+1)) /root/lanremote-relay/tunnel.log 2>/dev/null | grep -c 'Lost connection')"
printf " HTTP/2 注册 %s 失败 %s 掉线 %s\n" \
"$(tail -n +$((H0+1)) /root/lanremote-relay/tunnel-h2.log 2>/dev/null | grep -c 'Registered tunnel connection')" \
"$(tail -n +$((H0+1)) /root/lanremote-relay/tunnel-h2.log 2>/dev/null | grep -c 'Failed to dial')" \
"$(tail -n +$((H0+1)) /root/lanremote-relay/tunnel-h2.log 2>/dev/null | grep -c 'Lost connection')"
echo
echo "── watchdog 处置(本轮)──"
tail -12 /root/lanremote-relay/watchdog.log 2>/dev/null | sed 's/^/ /'
} > "$S" 2>&1
cat "$S"