mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 16:00:43 +00:00
琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞 - 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀? 鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException - 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴? 鏈嶅姟鍣ㄧ - 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級 - 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯 - 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺? 鏂囨。 - 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
141 lines
4.8 KiB
Bash
141 lines
4.8 KiB
Bash
#!/bin/bash
|
||
# 看门狗第三版:两个信号都查。
|
||
#
|
||
# 为什么还要改:
|
||
# 第二版只看 cloudflared 的 ha_connections 指标。
|
||
# 但"僵死连接"会把指标维持在 1 —— 计数还在,实际早断了。
|
||
# 这种时候看门狗以为一切正常,一直不管。
|
||
# (今早就遇到一次:浏览器 1033,指标却说有 1 条连接)
|
||
#
|
||
# 这一版:
|
||
# 信号 A:ha_connections == 0 -> 记一次"零连接"
|
||
# 信号 B:公网 /v1/health 打不通 -> 记一次"公网不通"
|
||
# 任一信号连续 2 次 -> 重启隧道
|
||
# 另外:隧道日志超过 10 分钟没新行 + 公网不通 -> 判定进程卡死,重启
|
||
set -u
|
||
|
||
RELAY_DIR=/root/lanremote-relay
|
||
URL_FILE="$RELAY_DIR/public_url.txt"
|
||
STATE_FILE="$RELAY_DIR/watchdog.state"
|
||
TUNNEL_LOG="$RELAY_DIR/tunnel.log"
|
||
METRICS=http://127.0.0.1:20241/metrics
|
||
LOG_TAG=lanremote-watchdog
|
||
|
||
# 连续几次公网不通才重启。
|
||
# 设 3(约 60 秒)而不是 2:短抖动让 cloudflared 自己重连就好,
|
||
# 频繁重启反而让它一直停在"正在重连"的状态。
|
||
THRESHOLD=3
|
||
STALE_MINUTES=10 # 日志多久没动静算卡死
|
||
# 两次重启之间至少隔这么久(秒)。
|
||
# 实测隧道重建只要 30~40 秒,原来设 120 秒太保守 ——
|
||
# 真断的时候会干等(日志里出现过"距上次重启才 118 秒,先不重启",
|
||
# 结果多断了 2 分钟)。
|
||
# 设 45 秒:既够 cloudflared 把连接建起来,又不会干等太久。
|
||
MIN_RESTART_GAP=45
|
||
|
||
log() {
|
||
logger -t "$LOG_TAG" "$1"
|
||
echo "[$(date '+%m-%d %H:%M:%S')] $1"
|
||
}
|
||
|
||
read_state() {
|
||
local key="$1" default="$2" value=""
|
||
if [ -f "$STATE_FILE" ]; then
|
||
value=$(grep "^$key=" "$STATE_FILE" 2>/dev/null | cut -d= -f2)
|
||
fi
|
||
[ -n "$value" ] && echo "$value" || echo "$default"
|
||
}
|
||
|
||
write_state() { printf 'zero=%s\nfail=%s\n' "$1" "$2" > "$STATE_FILE"; }
|
||
|
||
LAST_RESTART_FILE="$RELAY_DIR/watchdog.last_restart"
|
||
|
||
restart_tunnel() {
|
||
local why="$1"
|
||
local now last gap
|
||
now=$(date +%s)
|
||
last=0
|
||
[ -f "$LAST_RESTART_FILE" ] && last=$(cat "$LAST_RESTART_FILE" 2>/dev/null || echo 0)
|
||
gap=$((now - last))
|
||
|
||
# 连接数归零 = 真的断了,不是抖动 —— 这种不受间隔限制
|
||
local conns_now
|
||
conns_now=$(timeout 5 curl -s --max-time 4 "$METRICS" 2>/dev/null \
|
||
| grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}')
|
||
if [ "${conns_now:-1}" != "0" ] && [ "$gap" -lt "$MIN_RESTART_GAP" ]; then
|
||
# 刚重启过还没到间隔:这次先不重启,
|
||
# 让 cloudflared 自己把连接建起来(它本来就在重试)。
|
||
log "$why —— 但距上次重启才 ${gap} 秒(下限 ${MIN_RESTART_GAP} 秒),先不重启"
|
||
write_state 0 0
|
||
exit 0
|
||
fi
|
||
|
||
log "$why —— 重启隧道(距上次 ${gap} 秒)"
|
||
echo "$now" > "$LAST_RESTART_FILE"
|
||
systemctl restart lanremote-tunnel
|
||
write_state 0 0
|
||
sleep 25
|
||
log "重启后地址: $(cat "$URL_FILE" 2>/dev/null || echo '(还没拿到)')"
|
||
exit 0
|
||
}
|
||
|
||
ZERO=$(read_state zero 0)
|
||
FAIL=$(read_state fail 0)
|
||
|
||
# ---------- 信号 A:cloudflared 自报的连接数 ----------
|
||
CONNS=$(timeout 5 curl -s --max-time 4 "$METRICS" 2>/dev/null \
|
||
| grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}')
|
||
[ -z "$CONNS" ] && CONNS=""
|
||
|
||
# ---------- 信号 B:公网真的通吗 ----------
|
||
URL=$(cat "$URL_FILE" 2>/dev/null | tr -d '\r\n')
|
||
CODE="000"
|
||
if [ -n "$URL" ]; then
|
||
CODE=$(timeout 20 curl -4 -s -o /dev/null -w '%{http_code}' \
|
||
-H 'User-Agent: LanRemote/1.4.0' "$URL/v1/health" 2>/dev/null)
|
||
CODE=${CODE:-000}
|
||
fi
|
||
PUBLIC_OK=0
|
||
[ "$CODE" = "200" ] && PUBLIC_OK=1
|
||
|
||
# ---------- 信号 C:日志僵死了吗 ----------
|
||
LOG_STALE=0
|
||
if [ -f "$TUNNEL_LOG" ]; then
|
||
LAST=$(stat -c %Y "$TUNNEL_LOG" 2>/dev/null || echo 0)
|
||
NOW=$(date +%s)
|
||
if [ "$LAST" -gt 0 ] && [ $((NOW - LAST)) -gt $((STALE_MINUTES * 60)) ]; then
|
||
LOG_STALE=1
|
||
fi
|
||
fi
|
||
|
||
# ---------- 判断 ----------
|
||
if [ "$PUBLIC_OK" = "1" ]; then
|
||
# 公网通就是真的通,计数器清零
|
||
if [ "$ZERO" != "0" ] || [ "$FAIL" != "0" ]; then
|
||
log "公网恢复(HTTP 200),计数清零(之前 zero=$ZERO fail=$FAIL)"
|
||
fi
|
||
write_state 0 0
|
||
exit 0
|
||
fi
|
||
|
||
# 公网不通 —— 看是哪种原因
|
||
DETAIL="HTTP $CODE"
|
||
[ -n "$CONNS" ] && DETAIL="$DETAIL,ha_connections=$CONNS"
|
||
|
||
if [ "$LOG_STALE" = "1" ] && [ "$FAIL" -ge 1 ]; then
|
||
restart_tunnel "日志 ${STALE_MINUTES} 分钟没动静加上公网不通(进程卡死)"
|
||
fi
|
||
|
||
FAIL=$((FAIL + 1))
|
||
if [ -n "$CONNS" ] && [ "$CONNS" = "0" ]; then
|
||
ZERO=$((ZERO + 1))
|
||
fi
|
||
|
||
log "公网不通($DETAIL),连续第 $FAIL 次(零连接 $ZERO 次)"
|
||
|
||
if [ "$FAIL" -ge "$THRESHOLD" ] || [ "$ZERO" -ge "$THRESHOLD" ]; then
|
||
restart_tunnel "连续 $FAIL 次公网不通(含 $ZERO 次零连接)"
|
||
fi
|
||
|
||
write_state "$ZERO" "$FAIL"
|