如何在Azure创建API/Azure Function上传SFTP文件至Azure Data Lake Storage
Azure Function/API 实现SFTP到ADLS文件传输方案
你可以按以下步骤落地实现,不需要依赖额外第三方中间件:
前置依赖准备
- 创建基于.NET的Azure Function项目(推荐用Isolated Worker模型,长期支持更好),通过NuGet安装三个必需包:
SSH.NET:用于建立SFTP连接、拉取源端文件Azure.Storage.Files.DataLake:Azure官方ADLS Gen2 SDK,用于操作目标存储- 可选装
Polly:用于做接口调用的异常重试
- 参考资料不需要找复杂的完整开源项目,下面的核心代码已经覆盖90%以上通用场景,官方SDK内置示例也覆盖了分块上传、特殊鉴权等边缘场景的写法,按需调整即可。
核心实现逻辑
- 第一步:配置敏感参数
把SFTP服务地址、端口、登录用户名、密码/私钥内容,ADLS存储账号连接字符串、目标文件系统名、上传目标路径全部存在Azure Function的应用程序配置中,代码运行时通过Environment.GetEnvironmentVariable()读取,禁止硬编码敏感信息。 - 第二步:SFTP文件拉取
所有连接、流对象都用using块包裹,自动释放资源,避免连接泄漏。核心参考代码:// 从环境变量读取SFTP配置 var sftpHost = Environment.GetEnvironmentVariable("SftpHost"); var sftpPort = int.Parse(Environment.GetEnvironmentVariable("SftpPort")); var sftpUser = Environment.GetEnvironmentVariable("SftpUser"); var sftpPwd = Environment.GetEnvironmentVariable("SftpPwd"); var sftpSourcePath = Environment.GetEnvironmentVariable("SftpSourceDir"); using var sftpClient = new SftpClient(sftpHost, sftpPort, sftpUser, sftpPwd); sftpClient.Connect(); // 过滤掉目录、隐藏文件,只取需要同步的实体文件 var syncFiles = sftpClient.ListDirectory(sftpSourcePath) .Where(item => !item.IsDirectory && !item.Name.StartsWith(".")) .ToList(); foreach (var file in syncFiles) { using var memoryStream = new MemoryStream(); sftpClient.DownloadFile(file.FullName, memoryStream); memoryStream.Position = 0; // 流转给ADLS上传方法 await UploadToAdlsAsync(memoryStream, file.Name); } sftpClient.Disconnect(); - 第三步:ADLS文件上传
直接用从SFTP拉取的内存流上传,不需要落盘到Function本地临时目录,减少IO开销。核心参考代码:async Task UploadToAdlsAsync(Stream fileStream, string fileName) { var adlsConnStr = Environment.GetEnvironmentVariable("AdlsConnString"); var adlsFileSystem = Environment.GetEnvironmentVariable("AdlsFileSystem"); var adlsTargetDir = Environment.GetEnvironmentVariable("AdlsTargetDir"); var serviceClient = new DataLakeServiceClient(adlsConnStr); var fileSystemClient = serviceClient.GetFileSystemClient(adlsFileSystem); var directoryClient = fileSystemClient.GetDirectoryClient(adlsTargetDir); var targetFile = directoryClient.GetFileClient(fileName); // 大文件自动分块上传,避免内存溢出 var uploadOptions = new DataLakeFileUploadOptions { TransferOptions = new StorageTransferOptions { MaximumConcurrency = 2, InitialTransferSize = 100 * 1024 * 1024 } }; await targetFile.UploadAsync(fileStream, uploadOptions, cancellationToken: default); } - 第四步:触发方式配置
- 要做成可手动调用的API,就给Function加
HttpTrigger触发器,支持调用时传参指定SFTP源路径、ADLS目标路径 - 要做定时自动同步,就加
TimerTrigger触发器,配置Cron表达式按固定周期执行即可
- 要做成可手动调用的API,就给Function加
落地注意事项
- 大文件适配:单文件超过200MB时,不要全量加载到内存,可以把SFTP的下载流直接管道式传给ADLS上传方法,不用先把整个文件读到MemoryStream,大幅降低Function内存占用。
- 重复同步处理:建议加简单的同步状态记录,比如把已上传文件的文件名+最后修改时间存在Azure表存储里,每次同步前先比对,避免重复上传覆盖已有文件。
- 网络连通:如果SFTP部署在内网,需要给Azure Function配置VNet集成,确保Function运行时能和SFTP服务网络打通,否则会出现连接超时。
- 安全优化:ADLS鉴权可以不用连接字符串,开启Function的系统托管标识,给标识分配存储账号的
Storage Blob Data Contributor角色,降低密钥泄露风险。 - 异常重试:SFTP连接波动、ADLS服务限流这类临时异常,用Polly配置3-4次指数退避重试,不要因为单次临时错误导致整个同步任务失败。
内容的提问来源于stack exchange,提问作者Venkatesh
相关产品推荐
相关产品推荐

