执行摘要
- 一句话:为 v1 进程管理器关闭流程日志补充进程名与 PID
- 推荐动作:值得快速浏览:作为日志可观测性小改进,已获 maintainer 批准,可安全合并。后续可将 send sigterm 日志降为 debug,与 #50590 的日志噪音治理方向对齐;无需精读。
功能与动机
PR body 指出 shutdown 函数被多处使用,缺少进程名或进程类型时难以判断是哪个 process manager 触发关闭;且该流程只在退出时调用一次,附加进程名不会造成明显冗余。作者希望补充 name 与 pid 等进程元信息,以提供更多排障上下文。
实现拆解
- 变更入口:唯一改动文件为 vllm/v1/utils.py,核心函数为全局 shutdown(procs, timeout)。
- 启动日志增强:logger.debug 的格式串追加 names=%s,传入 (',').join([proc.name for proc in procs]),一次性列出所有待关闭进程名。
- SIGTERM 阶段:在 proc.terminate() 前对每个存活进程新增 logger.info,输出 send sigterm to process 。
- 强制 kill 阶段:将 remaining_pids 改为 remaining_procs((pid, name) 元组列表),强杀前逐条 logger.warning 打印进程名与 pid,再调用 kill_process_tree(pid)。被强杀的进程集合与顺序保持不变。
- 配套改动:无测试、配置、schema 或部署变更。提交历史包含两次 merge main;CI 的 v1-core-plus-kv-plus-metrics 失败来自 v1/kv_offload/tiering/test_fs_tier.py 的 O_DIRECT/overlayfs 环境问题(已由 #49734 修复),与本 PR 无重叠。
关键文件:
vllm/v1/utils.py(模块 进程管理;类别 source;类型 logging;符号 shutdown): 唯一改动文件,shutdown() 是多进程关闭的核心入口,日志增强直接帮助定位关闭/强杀来源。
关键符号:shutdown
关键源码片段
vllm/v1/utils.py
唯一改动文件,shutdown() 是多进程关闭的核心入口,日志增强直接帮助定位关闭/强杀来源。
# vllm/v1/utils.py::shutdown —— 引擎退出时统一关闭所有子进程
def shutdown(procs: list[BaseProcess], timeout: float | None = None) -> None:
'''关闭进程列表,带超时保护。'''
if timeout is None:
# 未显式配置时保留 5 秒宽限期,供非用户配置的清理路径使用
timeout = 5.0
logger.debug(
'[shutdown] Process manager: start process_count=%d timeout=%ss names=%s',
len(procs),
timeout,
(',').join([proc.name for proc in procs]), # 启动时一次性列出进程名,便于定位触发方
)
# 向所有存活进程发送 SIGTERM,并逐个记录进程名
for proc in procs:
if proc.is_alive():
logger.info(
'[shutdown] Process manager: send sigterm to process %s', proc.name
)
proc.terminate()
# 在截止时间内等待优雅退出
deadline = time.monotonic() + timeout
for proc in procs:
remaining = deadline - time.monotonic()
if remaining <= 0:
break
if proc.is_alive():
proc.join(remaining)
# 对超时未退出的进程,记录 name 与 pid 后强制 kill 整棵进程树
remaining_procs = [
(proc.pid, proc.name)
for proc in procs
if proc.is_alive() and proc.pid is not None
]
if remaining_procs:
logger.warning(
'[shutdown] Process manager: force killing remaining processes count=%d',
len(remaining_procs),
)
for pid, proc_name in remaining_procs:
logger.warning(
'[shutdown] Process manager: force killing remaining process %s pid %d',
proc_name,
pid,
)
kill_process_tree(pid)
logger.debug_once('[shutdown] Process manager: complete')
评论区精华
inferact-vllm-bot(代表 @simon-mo 审批):变更正确,BaseProcess.name/.pid 总是可用;强杀循环实际调用 kill_process_tree(pid) 的进程集合与之前完全一致,无行为变化。两个可选小建议:
1. (',').join([...]) 可简化为生成器表达式;
2. send sigterm to process 的 INFO 日志会在每次正常关闭时每引擎进程输出一行,建议降为 debug,与 start/complete 日志保持一致。
inferact-vllm-bot(CI triage):15 个失败全部来自 v1/kv_offload/tiering/test_fs_tier.py,是 O_DIRECT 被 overlayfs 的 /tmp 拒绝的环境问题,已在 main 上由 #49734 修复,与本 PR 无关,可 rebase 或 force-merge。
- INFO 日志可能造成正常关闭噪音 (style): 非阻塞建议;合并时保持 INFO,可后续调整。
- 列表推导可简化为生成器 (style): 非阻塞 nit,不影响行为。
- CI 失败是否与 PR 相关 (other): 失败与 PR 无关,可 rebase 合并 main 或 force-merge。
风险与影响
- 风险:功能路径无变化,回归风险极低。唯一可感知的影响是正常关闭时新增 INFO 级逐进程日志,可能增加日志量,审阅者建议后续降为 debug。BaseProcess.name/.pid 在进程存活时始终可用,join 之后 is_alive 为 False 的进程不会被纳入 remaining_procs,不会访问已失效对象。进程名若包含逗号可能使 names 列表模糊,但实际可忽略。无自动化测试覆盖此日志变更,但风险低。
- 影响:影响范围仅限于 vllm/v1 进程管理 shutdown 路径的日志输出。对用户无功能影响;对运维与开发者,多进程部署(API server、engine core、KV offload 等)下可按进程名和 PID 区分是哪一层在关闭或超时被强杀,显著提升排障效率。对团队影响小,无部署与发布影响。
- 风险标记:正常关闭日志量增加, 无测试覆盖, CI 需 rebase 获取 #49734
关联脉络
- PR #49668 [graceful shutdown] fix http server start firstly before app signal handler register: 同为进程退出/优雅关闭路径的修复,可与本 PR 的 shutdown() 日志变更对照理解 vLLM 关闭生命周期。
- PR #50590 [UX] Reduce startup log noise: 同为启动/关闭日志策略调整,方向相反(本 PR 增加上下文,彼 PR 降低噪音),是同一日志质量治理脉络。
参与讨论