经跳板机SSH循环拉取文件报22端口连接重置问题排查
问题根因
加sleep仍复现问题,说明不是简单的高频访问拦截,核心原因有三个:
- 最核心的是SSH短连接耗尽sshd并发阈值:每次循环会新建2条SSH连接(本地→跳板机、跳板机→目标机),10次循环累计要建20条短连接。Linux下TCP连接关闭后会默认在TIME_WAIT状态停留60s才彻底释放,如果加的sleep时长不足60s,半开连接会一直占着sshd的连接配额。默认sshd配置的
MaxStartups参数为10:30:60,即未认证并发连接到10个时就开始按30%概率拒绝新连接,到60个全拒,20个连接刚好落在概率拒绝区间,所以是偶发报错;拆成5个文件跑时累计只有10条连接,刚好卡在阈值以下,就不会复现。 - 其次是rsync默认无重试、无超时兜底:跨机器链路哪怕出现毫秒级闪断,rsync会直接抛255错误退出,循环次数越多触发概率越高。
- 容易忽略的点是跳板机临时目录异常:如果临时目录存在残留文件锁、剩余空间不足,拉取后半段文件时会因为写入失败触发连接断开,拆分跑时总写入量达不到空间阈值就不会触发。
解决方案
按优先级从高到低操作:
- 开启SSH长连接复用,从根源减少连接数
配置后整个脚本执行周期内,本地到跳板机、跳板机到目标机仅各维持1条长连接,总连接数从20降到2,完全不会触发连接数阈值,不需要加长sleep。
编辑本地~/.ssh/config,添加如下配置:
登录跳板机,编辑跳板机的Host <跳板机IP> ControlMaster auto ControlPath ~/.ssh/ssh_mux_%h_%p_%r ControlPersist 10m~/.ssh/config,添加针对目标机的同款配置,把Host字段换成目标机IP即可。配置后SSH会自动复用已有连接,无需修改原有脚本逻辑。 - 给rsync增加容错参数
替换脚本中所有rsync命令,添加断点续传、超时配置,配合重试逻辑兜底网络抖动:
对稳定性要求高的话,可以给单文件拉取加3次重试逻辑,示例:# 跳板机内执行的拉取命令 rsync -avz --partial --append-verify --timeout=30 <目标机IP>:<源文件路径> <临时目录路径> # 本地执行的从跳板机拉取命令 rsync -avz --partial --append-verify --timeout=30 <跳板机IP>:<临时目录文件路径> <本地存储路径>retry=3 for ((i=0; i<retry; i++)); do rsync -avz --partial --append-verify --timeout=30 <源路径> <目标路径> && break sleep 5 done - 补全基础兜底配置
- 如果暂时不配置SSH长连接,循环内的sleep时长至少设为60s,覆盖TCP TIME_WAIT默认周期,保证半开连接彻底释放。
- 每次循环拉取文件前,先清空跳板机临时目录下的对应残留文件,提前检查临时目录剩余空间不小于所有待拉文件总大小的1.5倍,避免空间不足、文件锁导致的拉取失败。
- 精准排查手段
调整后仍报错的话,直接查看对应机器的sshd日志定位明确原因:- Debian/Ubuntu系日志路径:
/var/log/auth.log - RHEL/CentOS系日志路径:
/var/log/secure
日志会明确记录是连接数超限、IP被临时封禁、还是进程异常退出,如果确认是连接数阈值过低,直接调整sshd配置文件/etc/ssh/sshd_config中的MaxStartups、MaxSessions参数后重启sshd服务即可。
- Debian/Ubuntu系日志路径:
内容的提问来源于stack exchange,提问作者Tms91
相关产品推荐
相关产品推荐

