190 lines
8.1 KiB
Bash
190 lines
8.1 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# ════════════════════════════════════════════════════════════════
|
||
|
|
# 国内域名机 · 动态调优 · tune-from-env.sh
|
||
|
|
# Sovereign: TCS-0002∞ · ICE-GL∞ · 国作登字-2026-A-00037559
|
||
|
|
# 守护: 铸渊 · ICE-GL-ZY001
|
||
|
|
# ════════════════════════════════════════════════════════════════
|
||
|
|
#
|
||
|
|
# 服务器: GH-CVM-DOMAIN-PROD-01 / ZY-SVR-CN01
|
||
|
|
#
|
||
|
|
# 读 detect-env.sh 写出的 server-env.json, 依据 size_tier 决档,
|
||
|
|
# 写出 /data/guanghulab/.env.tune 让 bootstrap.sh source 用.
|
||
|
|
#
|
||
|
|
# 档位策略 (因果链 cc-003 · 动态适配):
|
||
|
|
# tiny <4G : 2C2G 实际档. 单进程 portal, nginx worker=512,
|
||
|
|
# 关 LFS / 关 forgejo runner / 关 docker compose 上层服务,
|
||
|
|
# systemd MemoryHigh 严格收紧
|
||
|
|
# small 4-6G : 4C4G 续费档. portal 2 进程, nginx worker=1024
|
||
|
|
# medium 6-12G: 4C8G 异变档. portal 4 进程, runner 可开
|
||
|
|
# large 12-24G: 不应该出现在域名机, 但兼容
|
||
|
|
# xlarge >=24G: 同上, 兼容
|
||
|
|
#
|
||
|
|
# 输出:
|
||
|
|
# 1. /data/guanghulab/.env.tune — bootstrap source 用
|
||
|
|
# 2. /opt/guanghulab/_logs/tune-decision-*.json — 决策回执
|
||
|
|
#
|
||
|
|
# ⚠️ 当前 .env.tune 真实作用域:
|
||
|
|
# bootstrap.sh source 这个文件后, 当前**真正影响行为的字段**:
|
||
|
|
# - PORTAL_INSTANCES → pm2 起 portal 时的 instances 数
|
||
|
|
# - NGINX_WORKER_CONN → 渲染 nginx/guanghulab.conf 时的 worker_connections
|
||
|
|
# - FORGEJO_ENABLED → bootstrap 是否在 /data/guanghulab/forgejo/ 起 forgejo
|
||
|
|
# (PR-6 才真正用, 这里只是预留)
|
||
|
|
# - LFS_ENABLED → 是否在 nginx 里开 client_max_body_size 大上限
|
||
|
|
# (PR-6 才真正用)
|
||
|
|
# - SWAP_GB → bootstrap 是否要建/扩 swap 文件
|
||
|
|
# 其他字段是档位决策的快照, 落档便于霜砚追溯.
|
||
|
|
# ════════════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
ENV_FILE="${ENV_FILE:-/opt/guanghulab/_logs/server-env.json}"
|
||
|
|
DATA_ROOT="${DATA_ROOT:-/data/guanghulab}"
|
||
|
|
DEPLOY_ROOT="${DEPLOY_ROOT:-/opt/guanghulab}"
|
||
|
|
|
||
|
|
if [ ! -f "$ENV_FILE" ]; then
|
||
|
|
echo "❌ [tune] 找不到 $ENV_FILE, 请先跑 detect-env.sh" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
if ! command -v jq >/dev/null 2>&1; then
|
||
|
|
echo "❌ [tune] 需要 jq (apt-get install -y jq)" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
SIZE_TIER="$(jq -r '.compute.size_tier' "$ENV_FILE")"
|
||
|
|
MEM_MB="$(jq -r '.compute.memory_total_mb' "$ENV_FILE")"
|
||
|
|
SWAP_MB="$(jq -r '.compute.swap_total_mb' "$ENV_FILE")"
|
||
|
|
CPU="$(jq -r '.compute.cpu_count' "$ENV_FILE")"
|
||
|
|
|
||
|
|
# ─── 档位 → 参数表 ────────────────────────────────────────────
|
||
|
|
case "$SIZE_TIER" in
|
||
|
|
tiny)
|
||
|
|
PORTAL_INSTANCES="1"
|
||
|
|
PORTAL_MAX_MEMORY_MB="384" # pm2 重启阈值 (单进程)
|
||
|
|
NGINX_WORKER_CONN="512"
|
||
|
|
NGINX_WORKER_PROCESSES="1" # 2C2G 单 worker 就够
|
||
|
|
FORGEJO_ENABLED="false" # 2C2G 跑不下 forgejo + portal
|
||
|
|
LFS_ENABLED="false"
|
||
|
|
NEED_SWAP_GB="1" # 内存不够, 给 1G swap 兜底
|
||
|
|
SYSTEMD_PORTAL_HIGH_MB="500"
|
||
|
|
SYSTEMD_PORTAL_MAX_MB="700"
|
||
|
|
NOTE="2C2G 实际档. portal 单进程, forgejo/lfs 关. 任何全量 git push 走灯塔, 这里不揽."
|
||
|
|
;;
|
||
|
|
small)
|
||
|
|
PORTAL_INSTANCES="2"
|
||
|
|
PORTAL_MAX_MEMORY_MB="512"
|
||
|
|
NGINX_WORKER_CONN="1024"
|
||
|
|
NGINX_WORKER_PROCESSES="2"
|
||
|
|
FORGEJO_ENABLED="false"
|
||
|
|
LFS_ENABLED="false"
|
||
|
|
NEED_SWAP_GB="0" # 4G 起够用, 不强制 swap
|
||
|
|
SYSTEMD_PORTAL_HIGH_MB="800"
|
||
|
|
SYSTEMD_PORTAL_MAX_MB="1200"
|
||
|
|
NOTE="4C4G 续费档. portal 双进程, 仍不开 forgejo (forgejo 留在灯塔)."
|
||
|
|
;;
|
||
|
|
medium)
|
||
|
|
PORTAL_INSTANCES="4"
|
||
|
|
PORTAL_MAX_MEMORY_MB="768"
|
||
|
|
NGINX_WORKER_CONN="2048"
|
||
|
|
NGINX_WORKER_PROCESSES="auto"
|
||
|
|
FORGEJO_ENABLED="true"
|
||
|
|
LFS_ENABLED="true"
|
||
|
|
NEED_SWAP_GB="0"
|
||
|
|
SYSTEMD_PORTAL_HIGH_MB="2000"
|
||
|
|
SYSTEMD_PORTAL_MAX_MB="3000"
|
||
|
|
NOTE="4C8G+ 档. 可选 forgejo + lfs. 这台升到这档说明冰朔升配了, 顺带把灯塔合并意图打开."
|
||
|
|
;;
|
||
|
|
large|xlarge)
|
||
|
|
PORTAL_INSTANCES="4"
|
||
|
|
PORTAL_MAX_MEMORY_MB="1024"
|
||
|
|
NGINX_WORKER_CONN="4096"
|
||
|
|
NGINX_WORKER_PROCESSES="auto"
|
||
|
|
FORGEJO_ENABLED="true"
|
||
|
|
LFS_ENABLED="true"
|
||
|
|
NEED_SWAP_GB="0"
|
||
|
|
SYSTEMD_PORTAL_HIGH_MB="3500"
|
||
|
|
SYSTEMD_PORTAL_MAX_MB="6000"
|
||
|
|
NOTE="超规格. 资源不再紧张, 全量功能开."
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "❌ [tune] 未知 size_tier=$SIZE_TIER" >&2
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
# 已有 swap >= 1G 时, 不再强制再加 (避免重复建 swapfile)
|
||
|
|
if [ "$NEED_SWAP_GB" = "1" ] && [ "$SWAP_MB" -ge 1024 ]; then
|
||
|
|
NEED_SWAP_GB="0"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# ─── 写 .env.tune ─────────────────────────────────────────────
|
||
|
|
TUNE_FILE="$DATA_ROOT/.env.tune"
|
||
|
|
mkdir -p "$(dirname "$TUNE_FILE")"
|
||
|
|
cat > "$TUNE_FILE" <<EOF
|
||
|
|
# Generated by domain-cn/tune-from-env.sh @ $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||
|
|
# 档位: $SIZE_TIER (基于 ${MEM_MB}MB 内存 / ${CPU} 核 / swap ${SWAP_MB}MB)
|
||
|
|
# 注: $NOTE
|
||
|
|
#
|
||
|
|
# ⚠️ 作用域说明:
|
||
|
|
# - bootstrap.sh source 这个文件
|
||
|
|
# - PORTAL_INSTANCES / NGINX_WORKER_CONN / FORGEJO_ENABLED /
|
||
|
|
# LFS_ENABLED / NEED_SWAP_GB 真正影响行为
|
||
|
|
# - 其他字段是档位决策快照, 给霜砚 / 冰朔追溯
|
||
|
|
SIZE_TIER=$SIZE_TIER
|
||
|
|
PORTAL_INSTANCES=$PORTAL_INSTANCES
|
||
|
|
PORTAL_MAX_MEMORY_MB=$PORTAL_MAX_MEMORY_MB
|
||
|
|
NGINX_WORKER_CONN=$NGINX_WORKER_CONN
|
||
|
|
NGINX_WORKER_PROCESSES=$NGINX_WORKER_PROCESSES
|
||
|
|
FORGEJO_ENABLED=$FORGEJO_ENABLED
|
||
|
|
LFS_ENABLED=$LFS_ENABLED
|
||
|
|
NEED_SWAP_GB=$NEED_SWAP_GB
|
||
|
|
SYSTEMD_PORTAL_HIGH_MB=$SYSTEMD_PORTAL_HIGH_MB
|
||
|
|
SYSTEMD_PORTAL_MAX_MB=$SYSTEMD_PORTAL_MAX_MB
|
||
|
|
EOF
|
||
|
|
chmod 644 "$TUNE_FILE"
|
||
|
|
|
||
|
|
# ─── 决策回执 ─────────────────────────────────────────────────
|
||
|
|
TS="$(date -u +%Y%m%d-%H%M%S)"
|
||
|
|
RECEIPT="$DEPLOY_ROOT/_logs/tune-decision-$TS.json"
|
||
|
|
mkdir -p "$DEPLOY_ROOT/_logs"
|
||
|
|
cat > "$RECEIPT" <<EOF
|
||
|
|
{
|
||
|
|
"_sovereign": "TCS-0002∞ · 国作登字-2026-A-00037559",
|
||
|
|
"_purpose": "domain-cn tune decision",
|
||
|
|
"decided_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||
|
|
"input": {
|
||
|
|
"size_tier": "$SIZE_TIER",
|
||
|
|
"memory_mb": $MEM_MB,
|
||
|
|
"swap_mb": $SWAP_MB,
|
||
|
|
"cpu_count": $CPU
|
||
|
|
},
|
||
|
|
"decision": {
|
||
|
|
"PORTAL_INSTANCES": $PORTAL_INSTANCES,
|
||
|
|
"PORTAL_MAX_MEMORY_MB": $PORTAL_MAX_MEMORY_MB,
|
||
|
|
"NGINX_WORKER_CONN": $NGINX_WORKER_CONN,
|
||
|
|
"NGINX_WORKER_PROCESSES": "$NGINX_WORKER_PROCESSES",
|
||
|
|
"FORGEJO_ENABLED": $FORGEJO_ENABLED,
|
||
|
|
"LFS_ENABLED": $LFS_ENABLED,
|
||
|
|
"NEED_SWAP_GB": $NEED_SWAP_GB,
|
||
|
|
"SYSTEMD_PORTAL_HIGH_MB": $SYSTEMD_PORTAL_HIGH_MB,
|
||
|
|
"SYSTEMD_PORTAL_MAX_MB": $SYSTEMD_PORTAL_MAX_MB
|
||
|
|
},
|
||
|
|
"note": "$NOTE",
|
||
|
|
"tune_file": "$TUNE_FILE"
|
||
|
|
}
|
||
|
|
EOF
|
||
|
|
|
||
|
|
echo "═══════════════════════════════════════════════════════════"
|
||
|
|
echo " [tune · domain-cn] 动态调优决策"
|
||
|
|
echo "═══════════════════════════════════════════════════════════"
|
||
|
|
echo " 档位: $SIZE_TIER (${MEM_MB}MB / ${CPU} 核 / swap ${SWAP_MB}MB)"
|
||
|
|
echo " Portal 进程: $PORTAL_INSTANCES (单进程上限 ${PORTAL_MAX_MEMORY_MB}MB)"
|
||
|
|
echo " Nginx worker: $NGINX_WORKER_PROCESSES 进程 / $NGINX_WORKER_CONN 连接"
|
||
|
|
echo " Forgejo: $FORGEJO_ENABLED"
|
||
|
|
echo " Git LFS: $LFS_ENABLED"
|
||
|
|
echo " 需要建 swap: $NEED_SWAP_GB G"
|
||
|
|
echo " systemd MemHi: ${SYSTEMD_PORTAL_HIGH_MB}MB / Max ${SYSTEMD_PORTAL_MAX_MB}MB"
|
||
|
|
echo " 注: $NOTE"
|
||
|
|
echo " 写入: $TUNE_FILE"
|
||
|
|
echo " 回执: $RECEIPT"
|
||
|
|
echo "═══════════════════════════════════════════════════════════"
|