Files
Genarrative/docs/technical/DEV_RUST_STACK_PORT_CONFLICT_PRECHECK_2026-05-09.md
2026-05-10 13:18:46 +08:00

2.5 KiB
Raw Blame History

本地 Rust 栈端口冲突预检

日期:2026-05-09

问题

执行完整本地栈启动命令时:

node scripts/run-bash-script.mjs scripts/dev-rust-stack.sh --spacetime-port 3101 --skip-spacetime

如果本机已有旧的 api-server、主站 Vite 或后台 Vite 进程仍在监听默认端口,脚本可能出现混合日志:

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:<api-port>/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-NetTCPConnectionWin32_Process 输出 pid / name / address / command,方便精确停止旧进程。

主站和后台 Vite 也追加 --strictPort,避免默认漂移到 30013103 等端口后让浏览器继续访问旧页面。

排障步骤

PowerShell 查看默认端口占用:

Get-NetTCPConnection -State Listen -LocalPort 3000,3102,8082,3101 -ErrorAction SilentlyContinue |
  Select-Object LocalAddress,LocalPort,OwningProcess |
  Sort-Object LocalPort

查看进程命令行:

Get-CimInstance Win32_Process |
  Where-Object { $_.ProcessId -in @(3000端口PID, 8082端口PID) } |
  Select-Object ProcessId,Name,CommandLine

停止确认可丢弃的旧本地开发进程:

Stop-Process -Id <pid> -Force

如果确实需要保留旧栈,可显式换端口启动新栈:

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