20260526 增加持续soak监控与本地回放工具

This commit is contained in:
2026-05-26 18:02:40 +08:00
parent cda7fdb135
commit 7e1c24fcc3
30 changed files with 4541 additions and 12 deletions

View File

@@ -2,6 +2,7 @@
# 复制为 .env 后可以在远端直接调整;所有路径默认相对 package 根目录。
# 最大运行轮次。重复执行 run_soak.sh 时会从已有最后一轮之后继续编号。
# 正整数表示固定运行轮次;负数(例如 -1)表示持续运行不自动停止;0 非法。
MAX_RUNS=3
# 两轮之间等待秒数。做连续无等待验收时设置为 0。
@@ -15,7 +16,7 @@ RIRS=afrinic,apnic,arin,lacnic,ripe
# 运行根目录。默认使用 package 根目录;如需把产物写到独立数据盘,可改成绝对路径。
RUN_ROOT="${PACKAGE_ROOT}"
# 保留最近多少轮 run 目录。旧 run 会由 rpki_daemon 自身或后续脚本策略清理。
# 保留最近多少轮 run 目录。持续运行模式建议设置为 5 或按磁盘容量评估。
RETAIN_RUNS=10
# 是否输出 compact report JSON。1 表示启用,0 表示关闭。

View File

@@ -77,6 +77,11 @@ validate_non_negative_int() {
[[ "$value" =~ ^[0-9]+$ ]] || die "$name must be an integer: $value"
}
validate_max_runs() {
[[ "$MAX_RUNS" =~ ^-?[0-9]+$ ]] || die "MAX_RUNS must be an integer: $MAX_RUNS"
[[ "$MAX_RUNS" != "0" ]] || die "MAX_RUNS must be non-zero; use a positive value for fixed runs or -1 for continuous mode"
}
validate_rsync_scope() {
case "$RSYNC_SCOPE" in
publication-point|module-root)
@@ -486,20 +491,30 @@ PY
apply_outer_retention() {
local dirs=()
local retain_limit="$RETAIN_RUNS"
local keep_run="${1:-}"
local run_dir
shopt -s nullglob
for run_dir in "$RUNS_ROOT"/run_[0-9][0-9][0-9][0-9]; do
[[ -d "$run_dir" ]] && dirs+=("$run_dir")
done
shopt -u nullglob
if (( ${#dirs[@]} <= RETAIN_RUNS )); then
if (( ${#dirs[@]} <= retain_limit )); then
return 0
fi
mapfile -t dirs < <(printf '%s\n' "${dirs[@]}" | sort)
local remove_count=$(( ${#dirs[@]} - RETAIN_RUNS ))
local index
for (( index = 0; index < remove_count; index++ )); do
rm -rf "${dirs[$index]}"
local remove_count=$(( ${#dirs[@]} - retain_limit ))
local removed_count=0
local candidate
for candidate in "${dirs[@]}"; do
if [[ -n "$keep_run" && "$(basename "$candidate")" == "$keep_run" ]]; then
continue
fi
rm -rf "$candidate"
removed_count=$((removed_count + 1))
if (( removed_count >= remove_count )); then
break
fi
done
}
@@ -519,6 +534,7 @@ run_one_round() {
local summary_state
mkdir -p "$run_dir" "$daemon_state_root"
apply_outer_retention "$run_id"
started_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
write_run_meta "$run_dir/run-meta.json" "running" "$run_index" "$run_id" "$sync_mode" \
"$snapshot_reason" "$previous_run_id" "$previous_success_value" "$started_at" "" \
@@ -573,7 +589,7 @@ main() {
require_command python3
require_command date
require_command find
validate_positive_int "MAX_RUNS" "$MAX_RUNS"
validate_max_runs
validate_non_negative_int "INTERVAL_SECS" "$INTERVAL_SECS"
validate_positive_int "RETAIN_RUNS" "$RETAIN_RUNS"
validate_rsync_scope
@@ -599,12 +615,20 @@ main() {
local max_index
local next_index
local run_forever=0
local stop_index=0
max_index="$(max_existing_run_index)"
next_index=$((max_index + 1))
local stop_index=$((max_index + MAX_RUNS))
if (( MAX_RUNS < 0 )); then
run_forever=1
echo "run_soak mode=continuous max_existing_run_index=$max_index next_run=$(printf 'run_%04d' "$next_index")"
else
stop_index=$((max_index + MAX_RUNS))
echo "run_soak mode=fixed max_existing_run_index=$max_index next_run=$(printf 'run_%04d' "$next_index") stop_run=$(printf 'run_%04d' "$stop_index")"
fi
local any_failed=0
while (( next_index <= stop_index )); do
while (( run_forever == 1 || next_index <= stop_index )); do
INVALID_DB_PATH=""
INVALID_STATE_PATH=""
INVALID_TMP_PATH=""
@@ -649,7 +673,7 @@ main() {
echo "completed run $(printf 'run_%04d' "$next_index") status=failed" >&2
any_failed=1
fi
if (( next_index < stop_index && INTERVAL_SECS > 0 )); then
if (( (run_forever == 1 || next_index < stop_index) && INTERVAL_SECS > 0 )); then
sleep "$INTERVAL_SECS"
fi
next_index=$((next_index + 1))