Notebook实例CLOSE_WAIT问题自查与处理
适用范围:ModelArts Notebook(包含JupyterLab、Code Server两种在线使用方式)。
问题现象
- Notebook实例偶发自动重启、页面卡顿或无法打开。
- 在终端中可观察到大量CLOSE_WAIT状态的网络连接不断堆积。
问题定位
- 打开Notebook实例,在JupyterLab界面左上角选择“Files > New > Terminal”,打开命令行窗口。具体操作,请参见在JupyterLab中新建Terminal。
- 执行以下命令,查看当前CLOSE_WAIT连接数。
ss -tan | grep CLOSE_WAIT | wc -l
屏幕会返回一个数字,例如0、16、180。
如果系统提示“ss: command not found”(ss命令不可用),可改用netstat:
netstat -tan | grep CLOSE_WAIT | wc -l
- 等待1~2分钟后,再次执行上述命令,判断连接数是否持续增长。
- 数字为0或保持不变:实例正常,无需处理。
- 数字持续增长(如每分钟增加10个以上):连接正在泄漏,请参考后续问题原因与解决方案。
- (可选)如需确认产生连接的程序,可执行以下命令:
ss -tanp | grep CLOSE_WAIT
每行末尾会显示进程名(如python、node),便于定位未关闭连接的代码或服务。
问题原因
通过上述定位确认CLOSE_WAIT连接持续增长后,可判断泄漏源为实例内运行的程序:
实例内运行的程序(如Python脚本、Web服务、数据库连接等)建立了网络连接但未正确关闭。对端关闭连接后,本地连接滞留在CLOSE_WAIT状态无法回收,不断堆积直至耗尽实例资源,导致实例卡顿甚至自动重启。
此类泄漏由程序代码未释放连接引起,需从代码侧修复。
解决方案
- 方案一:重启Notebook实例(临时处理措施) 在ModelArts控制台找到该Notebook实例,单击“重启”。具体操作,请参见启动/停止/删除Notebook实例。
- 重启后连接计数清零,实例可暂时恢复。
- 重启前请先保存代码,防止未保存内容丢失。
- 重启仅为临时处理措施,代码未修复时泄漏会再次发生。
- 方案二:在终端清理连接(临时处理措施,权限允许且ss可用时)
在JupyterLab终端执行以下命令:
ss -K state close-wait
作用:强制关闭处于CLOSE_WAIT状态的未及时关闭的连接,不影响正在运行的任务。
如果提示“permission denied”(权限不足),或提示ss命令不可用,请使用方案一重启实例。
- 方案三:从代码侧彻底修复连接泄漏
CLOSE_WAIT堆积的根源是程序建立连接后未关闭,需检查代码:
- 使用HTTP请求库(如requests、urllib)时,确认请求完成后正确关闭响应或会话。
- 使用socket或数据库连接时,确认连接用完后调用close()释放,建议放在finally块中,保证异常路径也能关闭连接。
- 排查确认泄漏源后,重启实例清理存量连接,验证修复效果。
避免的操作
不要kill服务进程:CLOSE_WAIT连接归属于运行中的程序进程,kill进程会导致任务中断、正在编辑的内容丢失。
常见问题
- 看到很多TIME_WAIT连接,正常吗?
正常。TIME_WAIT是TCP正常关闭后的短暂过渡状态,约60秒(2MSL)后自动回收,无需处理。需要关注的是CLOSE_WAIT。
- 偶发少量CLOSE_WAIT需要处理吗?
不需要。仅当连接持续增长并影响实例稳定性时才需要处理。
- 清理连接会中断运行中的任务吗?
不会。ss -K state close-wait命令仅清理已处于挂起状态的连接,不影响正在运行的任务。
- 为什么实例会自动重启?
运行的程序未正确关闭网络连接,导致CLOSE_WAIT连接不断堆积,达到一定程度后实例资源耗尽或健康检查异常,触发自动重启。请从代码侧检查并释放未关闭的连接。