vLLM服务卡顿?端口复用陷阱揭秘
·
vLLM 服务“能启动、能监听,但一访问就卡住”——端口复用(CLOSE_WAIT)踩坑记录
关键词:vLLM、OpenAI-API、curl 卡住、端口复用、CLOSE_WAIT、TCP 残留句柄
发生场景:
- Linux 服务器
- 多次反复启动/停止
python -m vllm.entrypoints.openai.api_server- 日志正常、端口监听正常,curl 却永远无响应
1. 表面现象
- 启动命令最后一行日志出现
Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) curl http://localhost:8000/v1/modelshang 住十几秒后报Connection timed out- 重启服务不提示端口占用,似乎一切正常,问题依旧
2. 根因:旧进程 TCP 句柄残留 → 端口复用陷阱
- 上一次 Ctrl+C / kill 时,父进程已死,但 子进程(HTTP 句柄)进入 CLOSE_WAIT
- Linux 内核允许 多个进程同时监听同一端口(SO_REUSEPORT 机制)
- 新请求被随机分发给旧句柄,旧句柄永远不会返回 HTTP,于是 curl 一直 SYN_ACK 卡住
3. 三步定位
3.1 看看到底几个进程在监听
netstat -tunlp | grep 8000
典型输出:
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 315034/python
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 330842/python # ← 两个 PID!
3.2 再确认句柄状态
lsof -i :8000
输出里能看到 同一端口两行 LISTEN,甚至还能出现 CLOSE_WAIT 状态的旧连接
3.3 看进程是否僵尸
ps -ef | grep vllm.entrypoints
如果 PID 315034 的启动时间比 330842 早很多,且 CPU 时间为 00:00:00,基本可判定是 残留句柄
3.4 我的检查过程

4. 一键解决:杀光所有旧句柄,重新单实例启动
# 1. 清掉所有 vLLM 主进程(包括残留子进程)
pkill -9 -f vllm.entrypoints.openai.api_server
# 2. 确认端口彻底释放
netstat -tunlp | grep 8000 # 应该**没有任何输出**
# 3. 重新启动(记得加 --host 0.0.0.0 强制 IPv4)
python -m vllm.entrypoints.openai.api_server \
--model ./Llama2-Chinese-7b-Chat-ms \
--dtype float16 \
--host 0.0.0.0 \
--port 8000 \
--max-model-len 4096 \
--served-model-name chatglm3-6b \
--max-num-batched-tokens 8192 \
--max-num-seqs 4 \
--gpu-memory-utilization 0.92 \
--chat-template "{% for message in messages %}{{ message.role + ': ' + message.content + '\n' }}{% endfor %}" \
--enable-auto-tool-choice \
--tool-call-parser hermes
5. 验证
curl http://localhost:8000/v1/models
秒回 JSON 即表示问题彻底解决
6. 防复发小贴士
| 场景 | 建议 |
|---|---|
| 频繁重启调试 | 每次启动前 pkill -f vllm 做“软复位” |
| 生产环境 | 用 systemd / supervisor 托管,确保 杀进程=杀进程组 |
| 端口仍被占用 | 用 fuser -k 8000/tcp 一键清句柄 |
| WSL | 关闭窗口前先 Ctrl+C 优雅退出,否则 CLOSE_WAIT 更常见 |
7. 总结
“能启动、能监听、但一访问就卡住” ≠ 模型加载慢,也不一定是防火墙,
90% 是 旧进程 TCP 句柄残留导致端口复用,
杀光所有 vLLM 进程 → 端口归零 → 单实例重启,即可瞬间满血复活!
如果本文帮你节省了 debug 时间,欢迎点赞/收藏/留言交流~
更多推荐


所有评论(0)