部署后上传至S3的Excel文件偶现0KB问题排查求助
这种部署后偶发的0KB文件问题确实头疼——本地跑的好好的,一上生产就间歇性出状况,结合你贴的代码,我帮你梳理几个关键的排查和修复方向:
1. 临时文件写入未彻底刷入磁盘
你写入本地临时文件的代码里,虽然用了using块,但手动调用fileStream.Close()的操作有点多余,更关键的是:在某些部署环境(比如容器、网络共享存储)下,CopyTo完成后操作系统可能还在缓存数据,没有彻底写入磁盘,这时候直接去读文件上传,就可能读到空文件。
修复建议:
把写入逻辑改成异步+强制刷盘,同时去掉多余的Close:
using (FileStream fileStream = new FileStream(newFileName, FileMode.Create)) { await file.CopyToAsync(fileStream); // 用异步版本避免阻塞线程 fileStream.Flush(true); // 强制把缓冲区数据刷到磁盘,而不是停留在内存缓存 }
2. 同步阻塞异步方法引发的线程混乱
你在主接口里用UploadFile(...).Wait()来等待异步上传完成,这在ASP.NET环境下是个高危操作——会导致线程池资源被占用,上下文混乱,甚至可能让文件资源的释放时机不可控。本地环境线程资源充足,所以不容易触发,但部署后高并发场景下就会间歇性出问题。
修复建议:
把主接口改成异步方法,用await替代Wait():
public async Task<ActionResult<string>> IngestTestMatrix([FromForm] Guid authenticateduserid, [FromForm] Guid testeventid, IFormFile filename) { // ... 其他业务代码 // 用await等待异步上传完成,避免线程阻塞 await Model.Managers.AmazonFileManager.UploadFile(newFileName, testeventid.ToString()); // ... }
3. 临时文件未清理引发的资源隐患
你创建了带Guid的临时目录,但代码里完全没有清理逻辑。部署环境中,如果大量请求堆积,可能出现磁盘空间不足,甚至极端情况下的文件资源竞争(虽然用了Guid概率低,但还是要防患)。
修复建议:
在try/finally块里添加清理逻辑,确保不管流程成功还是失败,临时文件都能被删除:
try { // ... 你的业务逻辑(解析、存库、上传) } catch (Exception ex) { // ... 现有异常处理逻辑 } finally { // 清理临时文件和目录,失败时记录日志不影响主流程 if (Directory.Exists(newDictName)) { try { Directory.Delete(newDictName, true); } catch (Exception cleanEx) { var cleanLog = new LoggingEvent(LoggingEventTypeEnum.Warning, "临时文件清理失败", cleanEx.Message, authenticateduserid.ToString()); new LoggingEventController().InsertLoggingEvent(authenticateduserid, cleanLog, LoggingEventTypeEnum.Warning); } } }
4. 上传前的文件状态检查缺失
现在的代码上传前没有检查文件是否存在、大小是否正常,一旦临时文件写入失败,直接上传就会得到0KB的空文件,而且你还不知道问题出在写入环节还是上传环节。
修复建议:
在UploadFile方法开头加上文件状态检查,提前发现问题并记录详细日志:
public static async Task UploadFile(string filePath, string itemGuid) { // 先检查文件状态 if (!File.Exists(filePath)) { throw new FileNotFoundException("待上传文件不存在", filePath); } var fileInfo = new FileInfo(filePath); if (fileInfo.Length == 0) { throw new InvalidOperationException($"上传前发现文件为空:{filePath}"); } // ... 后续S3上传逻辑 }
同时在上层异常处理里,把文件状态(大小、是否存在)加到日志里,方便排查:
catch (Exception ex) { var fileInfo = new FileInfo(newFileName); string fileStatus = fileInfo.Exists ? $"文件大小:{fileInfo.Length}字节" : "文件不存在"; rsp.message = $"{ex.Message.Replace("\"", "")} | {fileStatus}"; // ... 现有日志记录逻辑 }
5. 部署环境的存储特殊性排查
本地用的是本地磁盘,部署环境可能用的是网络存储(比如AWS EFS、容器挂载卷),这些存储的IO性能、缓存机制和本地磁盘不一样,容易出现写入延迟。
额外排查点:
- 查看部署环境的磁盘IO监控,有没有写入超时、队列堆积的情况
- 如果是容器部署,检查挂载卷的权限是否正确(应用进程要有读写权限),避免文件实际没写入成功
内容的提问来源于stack exchange,提问作者Susan

