启动 9Router 报 EADDRINUSE(端口 20128 被占用)怎么排查?
2026/9/13 16:09:09 网站建设 项目流程

启动 9Router 报 EADDRINUSE(端口 20128 被占用)怎么排查?

【免费下载链接】9routerUnlimited FREE AI coding. Connect Claude Code, Codex, Cursor, Cline, Copilot, Antigravity to FREE Claude/GPT/Gemini via 40+ providers. Auto-fallback, RTK -40% tokens, never hit limits.项目地址: https://gitcode.com/GitHub_Trending/9r/9router

运行9router启动服务时,终端抛出下面这个错误,说明默认服务端口 20128 已经被别的进程(或上一次没退干净的 9Router 实例)占住了:

Error: listen EADDRINUSE: address already in use :::20128

9Router 的默认端口是20128,控制面板和 OpenAI 兼容 API(http://localhost:20128/v1)都挂在同一个端口上。本文只处理这一种报错:定位占用 20128 的进程,然后要么结束它、要么换一个端口启动,最后用文档给出的健康检查确认服务真的起来了。排查依据来自 安装文档、本地部署文档 和 故障排除文档。

先确认报错与端口

EADDRINUSE的完整形式是listen EADDRINUSE: address already in use :::20128,报错里的端口号直接告诉你冲突发生在 20128。如果端口号不是 20128,说明你启动时改过端口,下面的命令把20128换成实际报错中的端口即可。

两条排查路径对应两种处理策略:

  • 路径 A(主路径):20128 被残留的 9Router 进程或可安全终止的进程占用 → 找到 PID 并结束该进程,再用原端口启动;
  • 路径 B(可选分支):端口被其他服务长期占用、不方便动 → 换端口启动 9Router。

路径 A:找到占用进程并结束它

macOS / Linux

安装文档给出的步骤是先查、后杀:

# 找到占用 20128 端口的进程,输出中会列出 PID lsof -i :20128 # 结束该进程(<PID> 替换为上面 lsof 输出中的进程号) kill -9 <PID>

kill -9是强制终止。执行前先核对lsof输出:确认这个 PID 是之前遗留的 9Router 实例或其他可以安全关掉的进程,再执行,避免误杀无关服务。

Windows

故障排除文档中针对 20128 的检查命令是:

netstat -ano | findstr :20128

输出中最后一列是 PID,用文档在进程清理场景中给出的 Windows 强杀命令结束它:

taskkill /PID <PID> /F

<PID>替换为netstat输出里的进程号。注意强杀前同样先确认这个 PID 对应的进程可以终止。

重新启动并确认数据未受影响

结束进程后直接重新运行9router即可。配置、API keys 和 combos 都保存在数据目录~/.9router,重启不会丢失这些内容。

路径 B:换端口启动(可选)

如果 20128 被一个不方便终止的服务长期占用,可以改用其他端口启动。安装文档给出的命令行方式:

9router --port 3000

CLI 的--help也确认了这个参数:-p, --port <port> Port to run the server (default: 20128)3000只是文档示例值,可替换为任意空闲端口。文档还给出了通过环境变量PORT配置端口的方式(见 安装文档“端口配置”一节)。

换端口有一个连带影响:客户端配置里写的是http://localhost:20128/v1(README 中 Cursor、Cline、Copilot 等集成示例都是这个地址),端口换掉后这些 Base URL 要同步改成新端口,否则客户端仍然连不上。

验证服务已正常监听

重启后按安装文档的验证方式确认:

curl http://localhost:20128/health

文档给出的预期响应(文档示例,version以实际版本为准):

{ "status": "ok", "version": "1.0.0" }

返回status: "ok"即说明服务在 20128 上正常监听。如果走了路径 B,把 URL 中的20128换成实际使用的端口再检查。另外可以用lsof -i :20128再确认一次:此时输出里应当是当前的 9Router 进程,而不是之前的冲突进程。

两个需要注意的点

  1. 文档间对“改端口”的描述不一致:本地部署文档 提到 “API port (20128) and dashboard port (3000) are configured in the application. To change them, you'll need to modify the source code or use environment variables if supported”,没有提到命令行参数;而 安装文档 和 CLI 自带的帮助文本都明确支持--port/-p。实际操作以安装文档和9router --help输出为准。
  2. 区分 EADDRINUSE 与 ECONNREFUSED:如果是客户端连不上并看到ECONNREFUSED/ “Cannot connect to localhost:20128”,那通常是 9Router 根本没在运行或端口被防火墙挡住,属于 故障排除文档 中 “Connection Refused” 一节的问题,和端口被占用不是同一件事,排查顺序是确认进程在跑、lsof -i :20128能看到监听、再检查防火墙。

完成以上任一路径、/health返回ok后,端口冲突即已解除;如果lsof里 20128 反复出现新的陌生进程,说明有别的服务在持续占用,此时应改用路径 B 固定使用另一个端口,而不是反复强杀。

【免费下载链接】9routerUnlimited FREE AI coding. Connect Claude Code, Codex, Cursor, Cline, Copilot, Antigravity to FREE Claude/GPT/Gemini via 40+ providers. Auto-fallback, RTK -40% tokens, never hit limits.项目地址: https://gitcode.com/GitHub_Trending/9r/9router

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询