Paramiko SSH连接传输120GB大文件3小时后被远程主机关闭如何解决
问题修复方案
你遇到的远程主机关闭连接问题核心是OVH网络节点/远程SSH服务会主动清理长时间无控制层心跳的长连接,同时你的传输逻辑没有断点续传、连接复用优化,以下是可直接落地的修改方案:
1. 新增SSH连接保活配置
在connect函数中加入客户端主动保活逻辑,每30秒向服务端发送心跳包,避免连接被主动回收,同时增大传输缓冲区提升速度:
def connect(): transport = paramiko.Transport((target_host, target_port)) transport.connect(None, target_username, target_pwd) # 新增保活配置,30秒发一次心跳包 transport.set_keepalive(30) sftp_client = paramiko.SFTPClient.from_transport(transport) # 增大SFTP请求缓冲区,提升单文件传输速度 sftp_client.MAX_REQUEST_SIZE = 1024 * 1024 * 4 green_print("SSH connected") return sftp_client, transport
2. 新增断点续传+异常自动重连逻辑
修改传输函数,避免单连接长时间运行,同时跳过已传输完成的文件,断连后自动重连继续传输:
def transfert(sftp, vm, object_path): os.chdir(os.path.split(object_path)[0]) parent = os.path.split(object_path)[1] try: sftp.mkdir(vm) except: pass for path, _, files in os.walk(parent): remote_dir = os.path.join(vm, path) try: sftp.mkdir(remote_dir) except: pass for filename in files: local_path = os.path.join(object_path, filename) remote_path = os.path.join(remote_dir, filename) # 循环重试上传,直到成功 while True: try: # 检查远程文件是否已存在且大小一致,一致则跳过 try: remote_stat = sftp.stat(remote_path) local_size = os.path.getsize(local_path) if remote_stat.st_size == local_size: print(f"跳过已传输文件:{filename}") break except FileNotFoundError: pass # 开启断点续传,设置4MB传输缓冲区 sftp.put(local_path, remote_path, resume=True, bufsize=1024*1024*4) print(f"传输完成:{filename}") break except (paramiko.SSHException, EOFError, ConnectionResetError): # 连接断开,自动重连 print(f"连接断开,正在重连...") sftp.close() transport.close() sftp, transport = connect()
3. 可选优化:拆分任务并行传输
如果带宽足够,可以把120G的文件拆成多个小任务,每个任务用独立的连接传输,单任务传输完成直接销毁连接,既避免单连接长时间存活,也能提升整体传输速度。
修改后的代码不需要改动你原有业务逻辑,直接替换对应函数即可解决超时问题,同时避免断连后重复传输已经完成的文件。
内容的提问来源于stack exchange,提问作者Adrien Masson
相关产品推荐
相关产品推荐

