bookworm-boot/patches/deploy-patches.sh
bookworm 5e0ff18aa1 feat: Bookworm Portable v1.5 — 8 fixes (P0 NDA + P1 banners + P2 perf)
- P1: Banner v1.3→v1.5, Hooks 29→34
- P1: 卸载脚本补删 更新Bookworm.lnk
- P1: git stash pop 安全检查
- P2: Playwright 检测改用 npm list
- P2: 代理端口扫描 500ms async 超时

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 23:34:27 +08:00

142 lines
4.9 KiB
Bash

#!/bin/bash
# ============================================================
# Bookworm Web API — 稳定性优化补丁部署脚本
# 用法: ssh root@8.138.11.105 'bash -s' < deploy-patches.sh
# ============================================================
set -euo pipefail
WEBDIR="/opt/bookworm-web"
BACKUP="$WEBDIR/backups/pre-stability-$(date +%Y%m%d_%H%M%S)"
echo "========================================="
echo " Bookworm API 稳定性补丁 v1.0"
echo "========================================="
# 1. 备份当前文件
echo "[1/6] 备份当前文件..."
mkdir -p "$BACKUP/src" "$BACKUP/routes"
cp "$WEBDIR/src/proxy.js" "$BACKUP/src/"
cp "$WEBDIR/src/llm-router.js" "$BACKUP/src/"
cp "$WEBDIR/src/circuit-breaker.js" "$BACKUP/src/"
cp "$WEBDIR/routes/admin.js" "$BACKUP/routes/"
echo " 备份到: $BACKUP"
# 2. 部署 proxy-v2
echo "[2/6] 部署 src/proxy.js (keepAlive + 重试 + SSE心跳)..."
cat > "$WEBDIR/src/proxy.js" << 'PROXYEOF'
PROXY_PLACEHOLDER
PROXYEOF
echo " [OK] proxy.js 已更新"
# 3. 部署 llm-router-v2
echo "[3/6] 部署 src/llm-router.js (SSE心跳 + backpressure + 重试)..."
cat > "$WEBDIR/src/llm-router.js" << 'ROUTEREOF'
ROUTER_PLACEHOLDER
ROUTEREOF
echo " [OK] llm-router.js 已更新"
# 4. 部署 circuit-breaker-v2
echo "[4/6] 部署 src/circuit-breaker.js (半衰期 + 管理端点 + 统计)..."
cat > "$WEBDIR/src/circuit-breaker.js" << 'CBEOF'
CB_PLACEHOLDER
CBEOF
echo " [OK] circuit-breaker.js 已更新"
# 5. 追加 Circuit Breaker 管理端点到 admin.js
echo "[5/6] 追加 Circuit Breaker 管理端点..."
# 检查是否已有 circuit-breaker 路由
if grep -q 'circuit-breaker' "$WEBDIR/routes/admin.js" 2>/dev/null; then
echo " [SKIP] admin.js 已含 circuit-breaker 路由"
else
# 在 admin.js 末尾的 }; 之前注入
# 策略: 在 server.js 中追加路由注册
cat >> "$WEBDIR/server.js.cb-patch" << 'PATCHEOF'
// ─── Circuit Breaker 管理端点 (稳定性补丁) ───
try {
const patchAdminRoutes = require('./patches/admin-cb-routes');
patchAdminRoutes(routes, deps);
} catch (_e) { console.warn('[patch] CB admin routes failed:', _e.message); }
PATCHEOF
# 实际注入方式: 直接修改 admin.js 在最后的 }; 前插入
ADMIN_FILE="$WEBDIR/routes/admin.js"
# 安全追加到函数体末尾 (最后一个 }; 前)
INJECT=$(cat << 'INJECTEOF'
// ─── Circuit Breaker 管理端点 (稳定性补丁) ───
routes['GET:/v1/admin/circuit-breaker'] = async (req, res) => {
requireAdmin(req);
const cb = deps.circuitBreaker;
const cbStatus = cb.getStatus ? cb.getStatus() : {};
const cbLog = cb.getTransitionLog ? cb.getTransitionLog(20) : [];
json(res, 200, { ok: true, breakers: cbStatus, recentTransitions: cbLog });
};
routes['POST:/v1/admin/circuit-breaker/reset'] = async (req, res) => {
requireAdmin(req);
const body = await parseJsonBody(req);
const cb = deps.circuitBreaker;
if (body.provider) {
cb.reset(body.provider);
json(res, 200, { ok: true, reset: body.provider });
} else if (cb.resetAll) {
cb.resetAll();
json(res, 200, { ok: true, reset: 'all' });
} else {
json(res, 400, { error: '请指定 provider' });
}
};
INJECTEOF
)
# 用 sed 在最后的 }; 前插入 (admin.js 最后一行是 };)
sed -i '$ i\'"$INJECT" "$ADMIN_FILE" 2>/dev/null || {
# sed 失败则用 python3
python3 -c "
import re
with open('$ADMIN_FILE', 'r') as f: content = f.read()
inject = '''$INJECT'''
# 在最后一个 }; 前插入
pos = content.rfind('};')
if pos > 0:
content = content[:pos] + inject + '\n' + content[pos:]
with open('$ADMIN_FILE', 'w') as f: f.write(content)
print(' [OK] admin.js 已注入 CB 端点 (python)')
else:
print(' [WARN] 未找到插入点')
"
}
echo " [OK] admin.js 已注入 CB 管理端点"
rm -f "$WEBDIR/server.js.cb-patch"
fi
# 6. 清理 Nginx 重复配置
echo "[6/6] 检查 Nginx 配置..."
NGINX_CONF="/etc/nginx/conf.d/bookworm-web.conf"
if [ -f "$NGINX_CONF" ]; then
# 统计 server 块数量
SERVER_COUNT=$(grep -c 'server_name bookworm.letcareme.com;' "$NGINX_CONF" 2>/dev/null || echo 0)
if [ "$SERVER_COUNT" -gt 2 ]; then
echo " [WARN] 发现 $SERVER_COUNT 个 server 块 (应为 2: HTTP+HTTPS)"
echo " 建议手动清理: vim $NGINX_CONF"
else
echo " [OK] Nginx 配置正常"
fi
fi
echo ""
echo "========================================="
echo " 补丁部署完成!"
echo "========================================="
echo ""
echo " 下一步:"
echo " 1. 语法检查: cd $WEBDIR && node --check server.js"
echo " 2. 重启服务: pm2 reload bookworm-web"
echo " 3. 验证健康: curl http://127.0.0.1:3211/health"
echo " 4. 验证CB端点: curl -H 'Authorization: Admin TOKEN' http://127.0.0.1:3211/v1/admin/circuit-breaker"
echo ""
echo " 回滚:"
echo " cp $BACKUP/src/* $WEBDIR/src/"
echo " cp $BACKUP/routes/* $WEBDIR/routes/"
echo " pm2 reload bookworm-web"
echo "========================================="