C# Azure WebJob读取Blob存储CSV文件运行15分钟后连接被强制关闭
问题原因
- 核心问题是代码在调用
blobClient.DownloadAsync()后,直接持有Blob存储返回的网络流逐行读取,且每读一行就同步执行密码重置操作。整个处理6000条记录的15分钟周期里,到Blob存储的TCP连接一直保持打开状态,且处理密码重置的时间段内连接处于空闲状态,会被Azure存储服务侧、中间网络设备的空闲超时策略主动断开,最终抛出SocketException (10054)连接被强制关闭的错误。 - 代码存在逻辑bug:判断空行的条件
if(line!=null || line != "")永远成立,当line为空字符串时line!=null判断为真,会把空行传入密码重置方法,平白增加不必要的处理耗时,拉长连接保持的总时长。 - 没有对Blob存储操作配置弹性重试策略,网络偶发抖动或者连接被重置时没有自动恢复能力。
修复方案
- 彻底分离Blob下载和业务处理逻辑:不要直接在Blob返回的网络流上边读边处理业务,先把整个CSV文件完整下载到本地临时文件或者内存流,下载完成后立刻释放Blob相关的连接资源,再从本地流/本地文件读取记录执行密码重置,从根源上避免长时持有Blob网络连接。
- 修复空行判断逻辑,使用
string.IsNullOrWhiteSpace()过滤无效空行,减少无意义的接口调用耗时。 - 为Blob服务客户端配置重试策略,应对偶发的网络波动。
修正后的核心代码参考:
var blobConnectionString = ConfigurationManager.AppSettings["azure_blob_connection"]; BlobServiceClient blobServiceClient = new BlobServiceClient(blobConnectionString); BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("resetaccountlist"); BlobClient blobClient = containerClient.GetBlobClient("testaccount.CSV"); if (await blobClient.ExistsAsync()) { // 先把整个Blob下载到本地临时文件,下载完成后自动断开和Blob存储的连接 var localTempPath = Path.GetTempFileName(); await blobClient.DownloadToAsync(localTempPath); // 读取本地文件处理业务,不再占用Blob网络连接 using (var streamReader = new StreamReader(localTempPath)) { while (!streamReader.EndOfStream) { var line = await streamReader.ReadLineAsync(); Console.WriteLine(line); // 修复空行判断逻辑 if(!string.IsNullOrWhiteSpace(line)) { UserService.ResetPassword(line); } } } // 处理完成后删除临时文件 File.Delete(localTempPath); Environment.Exit(0); } else { Console.WriteLine("---Blob file does not exist---"); }
额外说明:如果单条密码重置操作耗时过长,6000条记录总处理时长超过Azure WebJob的默认超时阈值,还需要在WebJob配置中调整作业超时时间,或者改用队列触发的方式分批处理记录,避免单作业运行过久触发平台超时。
内容的提问来源于stack exchange,提问作者MJ X
相关产品推荐
相关产品推荐

