You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js AWS Lambda中ssh2-sftp-client SFTP上传异常排查

问题描述

Node.js项目中使用ssh2-sftp-client实现本地文件夹单/多文件到SFTP目录的上传能力,上传逻辑采用Promise.all实现并发。代码本地测试运行正常,部署到AWS Lambda后日志显示上传成功,但实际SFTP目录内找不到对应上传文件,问题代码如下:

exports.handler= async (event)=>{    
 var Files = await Promise.all(FilesLIst.map(async (file) =>UploadToFtp(_customer,dir,file)));
}
function UploadToFtp(_customer,dir,file){
        let remote = _customer.FTPPath + '/' + file;
        let client = new Client;
        const config = {
            host: _customer.FTPHost,
            port:_customer.FTPPort,
            username:_customer.FTPUserName,
            password: _customer.FTPPassword,
          };
        return new Promise((res,rej)=>{
                client.connect(config)
                .then(() => {
                    let data=fs.readFileSync(dir+'/'+file);
                    return client.put(data, remote);
                })
                .then(() => {
                    return client.end();                   
                })
                .catch(err => {
                    console.error(err.message);
                });
        })
}
排查修复方向
  • 修复Promise状态流转缺陷(最高优先级)
    现有代码属于典型的Promise反模式:外层自定义包装的Promise从未调用res()触发成功状态,catch块也未调用rej()抛出错误。
    这会直接导致两个核心问题:
    1. Promise.all不会等待SFTP连接建立、文件上传、连接关闭的完整流程执行完成,Lambda会在事件循环清空后立刻冻结执行环境,此时文件可能还未完全写入SFTP服务端,连接未正常断开,服务端会直接丢弃未完成的临时上传文件
    2. 所有上传过程中的报错都被catch块静默吞掉,不会向外抛出,Lambda会默认所有任务执行成功,造成"上传成功"的假象
      修复方式:移除多余的外层Promise包装,直接返回ssh2-sftp-client原生的Promise链,流程正常结束后返回明确的成功状态,报错时直接向外抛出异常,禁止静默吞错。
  • 校验配置与路径正确性
    1. 核对Lambda环境中配置的SFTP地址、端口、账号密码、远端根路径FTPPath,确认和本地测试环境指向同一套SFTP服务,避免出现连测试环境却到生产环境查找文件的问题
    2. 本地文件路径、远端SFTP路径统一使用Node.js原生path.join()方法拼接,不要手动拼接/,避免因Lambda执行环境工作目录和本地不一致导致的文件读取失败、远端路径格式错误
    3. 确认Lambda中待上传的文件都存储在/tmp目录下,Lambda执行环境仅/tmp目录具备写入权限,如果业务逻辑存在先写本地文件再上传的步骤,非/tmp路径会直接写入失败。
  • 优化SFTP客户端实现逻辑
    1. 不要为每个上传文件单独新建SFTP连接,所有文件上传复用同一个客户端实例,减少连接建立开销的同时,避免短时间内创建大量连接触发SFTP服务端的限流、IP拦截规则
    2. 调用client.end()关闭连接前,确认文件上传操作已完全落盘,可在上传完成后校验远端文件大小与本地文件一致,再执行连接关闭操作
    3. 给SFTP客户端配置合理的连接、传输超时时间,避免连接静默断开导致的上传失败无感知。
  • 调整并发与网络配置
    1. 不要使用无并发限制的Promise.all执行批量上传,增加并发数控制(建议单批同时上传不超过3个文件),避免高并发下出现连接超时、服务端拒绝连接的问题
    2. 检查Lambda网络配置:如果SFTP服务端部署在内网,确认Lambda已接入对应VPC,安全组出方向放开SFTP对应端口的访问权限,网络ACL未拦截对应流量
    3. 核对SFTP服务端的访问日志,确认Lambda发起的连接是否正常到达服务端、文件写入请求是否被正常处理,排除服务端自动清理异常连接上传文件的规则影响。
  • 验证Lambda退出时机
    在Promise.all执行完成后增加明确的完成日志,打印所有文件对应的远端路径、上传状态,确认Lambda是在所有上传逻辑执行完成后才退出,不存在提前终止执行的问题。

内容的提问来源于stack exchange,提问作者G S M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.08 16:15:16