Files
planet/docs/technical/zh/ops-planet-sh-startup.md
2026-04-28 16:10:17 +08:00

155 lines
4.3 KiB
Markdown
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.
# planet.sh 启动性能优化
## 背景
`planet.sh` 管理所有服务的启动/停止/重启。原有实现存在以下问题:
1. AI Provider 每次都重新构建(即使代码未变)
2. 杀端口速度极慢(最长等 45 秒)
3. 端口绑定检测用 Python 子进程(每次 ~300ms
4. 无参 `restart``restart -b` 行为不一致
## 问题一AI Provider 每次重建
### 根因
构建戳文件存放在 `/tmp/`WSL/Linux 重启后 `/tmp` 被清空,导致三个条件中的"戳文件非空"这一条始终不满足,进而判定需要重建:
```bash
# 三个条件必须同时成立才跳过重建
image_exists AND stamp_non_empty AND fingerprint_match
```
### 修复
将戳文件路径从 `/tmp/` 改到持久路径:
```bash
AI_PROVIDER_BUILD_STAMP_FILE="$HOME/.cache/planet/aiprovider_build.sha256"
```
写入时确保目录存在:
```bash
write_ai_provider_build_stamp() {
mkdir -p "$(dirname "$AI_PROVIDER_BUILD_STAMP_FILE")"
compute_ai_provider_build_fingerprint > "$AI_PROVIDER_BUILD_STAMP_FILE"
}
```
### fingerprint 计算提速
原实现对整个 `aiprovider/` 打 tar 包再算 SHA大目录下耗时可达数秒。改为 `find + stat`(只读文件元信息,不读内容):
```bash
compute_ai_provider_build_fingerprint() {
find aiprovider \
-type f \
! -path '*/__pycache__/*' \
! -name '*.pyc' \
! -name '*.pyo' \
| LC_ALL=C sort \
| xargs -r stat --format="%Y %s %n" 2>/dev/null
sha256sum docker-compose.yml docker-compose.simple.yml 2>/dev/null
python3 "$SCRIPT_DIR/scripts/compute_aiprovider_dependency_fingerprint.py" 2>/dev/null
}
```
速度提升约 10 倍大量小文件场景误报率相同mtime+size 变化 ≡ 文件被修改)。
### 跳过重建的原理
fingerprint 一致时不执行 `docker compose build`,而是:
```bash
docker start planet_aiprovider # 启动已存在的容器,几秒内完成
```
`docker stop` 停容器,不删镜像;`cleanup_exit_containers` 删已退出容器,不删镜像。下次 `docker start` 会从现有镜像直接创建并启动容器。
## 问题二:杀端口速度慢
### 原因
`wait_for_port_release` 默认最多等 45 秒15 次 × 3 秒)。
### 修复
将后台进程清理场景的超时缩短至 3 秒TERM→1.5s→KILL→1.5s
```bash
PORT_RELEASE_ATTEMPTS=15
PORT_RELEASE_INTERVAL=0.2 # 每次等 0.2s,总计 3s
# cleanup_backend_processes / kill_port_if_requested
wait_for_port_release "$port" 15 0.2
```
`wait_for_port_release` 增加可选参数,允许不同场景使用不同超时:
```bash
wait_for_port_release() {
local port="$1"
local max_attempts="${2:-$PORT_RELEASE_ATTEMPTS}"
local interval="${3:-$PORT_RELEASE_INTERVAL}"
...
}
```
## 问题三:端口检测用 Python
### 原因
`can_bind_port``python3 -c "import socket..."` 检测端口,每次调用约 300ms。
### 修复
优先使用系统工具(~10msPython 作为兜底:
```bash
can_bind_port() {
local port="$1"
if command -v ss >/dev/null 2>&1; then
! ss -tlnH 2>/dev/null | awk '{print $4}' | grep -qE ":${port}$"
return
fi
if command -v lsof >/dev/null 2>&1; then
[ -z "$(lsof -tiTCP:"${port}" -sTCP:LISTEN 2>/dev/null)" ]
return
fi
python3 - "$port" <<'PY'
import sys, socket
p = int(sys.argv[1])
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind(("", p)); s.close(); sys.exit(0)
except OSError:
sys.exit(1)
PY
}
```
## 问题四restart 行为不一致
### 现象
- `restart -b`:停全部服务 → 检查 AI Provider fingerprint → 按需重建 → 启动
- `restart`(无参):停全部服务 → AI Provider 总是判定需要重建(因戳文件在 /tmp
### 修复
修复戳文件路径后,无参 `restart` 同样使用 `stop + start`fingerprint 检查正常生效,行为与 `restart -b` 完全一致。无需额外代码变更。
## 其他:移除不必要的 sleep
启动链路中两处 `sleep 3` 在实际已有健康检查覆盖的情况下多余,已移除:
- `start_backend_service`:数据库健康检查通过后的 `sleep 3`
- `restart_database_service`:重启后的等待 `sleep 3`
## 相关文件
- `planet.sh` — 全量修改
- `scripts/compute_aiprovider_dependency_fingerprint.py` — 依赖 fingerprint未改动