通过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
相关产品推荐
相关产品推荐

