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

通过SFTP上传文件时Azure Function触发两次的问题求助

Azure Function BlobTrigger SFTP上传触发两次的解决方案

问题核心原因

SFTP客户端(WinSCP、FileZilla等)的分段上传/临时文件机制是主要诱因:这类工具上传文件时,通常会先创建一个带临时后缀(如.part、.tmp)的中间文件,上传完成后再重命名为目标文件名。存储账户会针对这两个操作(临时文件创建、最终文件创建)各发送一次Blob创建事件,导致BlobTrigger被触发两次。而直接上传到存储账户时,文件是一次性写入,只会触发一次事件。

可行解决方案

1. 在函数内过滤临时文件

在函数代码中添加判断逻辑,只处理符合正式命名规则的文件,忽略临时文件:

// C# 示例
public static void Run([BlobTrigger("container/{name}", Connection = "AzureWebJobsStorage")] Stream myBlob, string name, ILogger log)
{
    // 忽略带临时后缀的文件
    if (name.EndsWith(".part") || name.EndsWith(".tmp"))
    {
        log.LogInformation($"跳过临时文件: {name}");
        return;
    }
    
    // 正式处理逻辑
    log.LogInformation($"处理文件: {name}");
}

2. 调整SFTP客户端上传设置

修改SFTP工具的上传模式,禁用临时文件生成:

  • WinSCP:在传输设置中,将「上传模式」改为「直接」(默认是「断点续传」),避免生成.tmp临时文件。
  • FileZilla:进入「编辑」→「设置」→「传输」,关闭「使用断点续传(默认)」选项,或者在站点设置中调整传输模式为「二进制」并禁用临时文件。
  • PowerShell SFTP:使用Set-SFTPFile时,指定-TransferType Binary并确保没有启用分段上传参数。

3. 函数内部实现去重逻辑

如果无法避免重复事件,可以通过记录已处理文件的唯一标识(如Blob的ETag、文件名+创建时间)来实现去重:

  • 将已处理的标识存储到Azure Table Storage或Redis中。
  • 每次触发时先查询该标识是否存在,存在则跳过处理,不存在则执行逻辑并记录标识。

4. 检查存储账户事件订阅

确认存储账户的Blob事件订阅仅订阅了Microsoft.Storage.BlobCreated事件,没有重复订阅或额外订阅Microsoft.Storage.BlobRenamed等事件(部分SFTP重命名操作可能触发该事件)。

额外排查点

  • 确认host.json中的extensions.blobTrigger配置没有开启多余的检测逻辑,比如trackBlobCreated是否设为true(默认是true,但直接上传正常的话这个不是问题)。
  • 检查函数的日志,确认两次触发对应的Blob名称是否不同(一个是临时文件,一个是最终文件),验证临时文件的猜想。

内容的提问来源于stack exchange,提问作者tunahanyollar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:50:27