# 本地 Rust 栈端口冲突预检 日期:`2026-05-09` ## 问题 执行完整本地栈启动命令时: ```bash node scripts/run-bash-script.mjs scripts/dev-rust-stack.sh --spacetime-port 3101 --skip-spacetime ``` 如果本机已有旧的 `api-server`、主站 Vite 或后台 Vite 进程仍在监听默认端口,脚本可能出现混合日志: ```text Port 3000 is in use, trying another one... Error: Os { code: 10048, kind: AddrInUse } process didn't exit successfully: `server-rs\target\debug\api-server.exe` ``` 其中 `wait_for_api_server` 只探测 `http://127.0.0.1:/healthz`。当旧 `api-server` 仍监听 `8082` 时,健康检查会命中旧进程并误判新服务已就绪;随后新 `cargo run` 真正绑定 `8082` 时失败。与此同时,Vite 默认会在 `3000` 被占用时漂移到下一个端口,导致浏览器仍可能打开旧前端。 ## 处理 `scripts/dev-rust-stack.sh` 在进入 SpacetimeDB publish 和 Rust 编译前,先检查三类端口是否可绑定: 1. Rust `api-server`:默认 `127.0.0.1:8082`。 2. 主站 Vite:默认 `0.0.0.0:3000`。 3. 后台 Vite:默认 `127.0.0.1:3102`。 端口被占用时,脚本会直接失败并打印监听进程。Windows 本地会通过 `Get-NetTCPConnection` 与 `Win32_Process` 输出 `pid / name / address / command`,方便精确停止旧进程。 主站和后台 Vite 也追加 `--strictPort`,避免默认漂移到 `3001`、`3103` 等端口后让浏览器继续访问旧页面。 ## 排障步骤 PowerShell 查看默认端口占用: ```powershell Get-NetTCPConnection -State Listen -LocalPort 3000,3102,8082,3101 -ErrorAction SilentlyContinue | Select-Object LocalAddress,LocalPort,OwningProcess | Sort-Object LocalPort ``` 查看进程命令行: ```powershell Get-CimInstance Win32_Process | Where-Object { $_.ProcessId -in @(3000端口PID, 8082端口PID) } | Select-Object ProcessId,Name,CommandLine ``` 停止确认可丢弃的旧本地开发进程: ```powershell Stop-Process -Id -Force ``` 如果确实需要保留旧栈,可显式换端口启动新栈: ```bash node scripts/run-bash-script.mjs scripts/dev-rust-stack.sh \ --skip-spacetime \ --spacetime-port 3101 \ --api-port 8090 \ --web-port 3001 \ --admin-web-port 3103 ``` ## 验证 1. `bash -n scripts/dev-rust-stack.sh` 通过。 2. 默认端口被占用时重新运行完整栈,脚本应在 publish 前失败并打印占用进程。 3. 清理占用进程或换端口后,重新启动时不再出现 Vite 端口漂移或 `api-server` `AddrInUse`。