【发布时间】:2017-11-17 15:08:01
【问题描述】:
我目前维护一个将近 3 年的 ASP .Net MVC 网站,该应用程序运行在 IIS(现在在 IIS 7 中) 并使用 ASP .Net 4 Framework .它几乎每天都被客户使用,并且有很多上传-下载文件的交易。它还使用 ELMAH 作为未处理的异常处理。该应用程序运行良好,直到过去几个月,有很多用户报告说他们无法下载文件,但没有任何错误消息,下载过程什么也没做,浏览器控制台也没有登录。经过多次检查,所有具有下载功能的菜单都使用http响应
Response.Clear();
Response.Cache.SetCacheability(HttpCacheability.Private);
Response.Expires = -1;
Response.Buffer = true;
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Length", Convert.ToString(file_in_bytes.Length));
Response.AddHeader("Content-Disposition"
, string.Format("{0};FileName=\"{1}\"", "attachment", fileName));
Response.AddHeader("Set-Cookie", "fileDownload=true; path=/");
Response.BinaryWrite(hasil);
Response.End();
而且似乎没有任何问题(开发服务器中没有编译或运行时错误)。我们还检查了 Elmah 的日志,但没有出现相关的错误消息。在我们的服务器管理团队在 IIS 中回收应用程序池之后,这个问题暂时消失了。
这个网站也和另一个网站共享应用程序池,当这个错误发生时,两个应用程序都会受到影响,只有下载功能受影响,其他功能如从数据库中检索数据,插入/编辑/删除数据工作正常。
我还检查了 Web 服务器事件查看器,但那里没有任何错误。对我们来说非常奇怪的是,在我们回收应用程序池后,这个错误会暂时消失,而在几天、几周或几个月后,这个错误又会突然出现。
有没有我们遗漏的日志?或者下载代码有问题? 为什么它在回收应用程序池后暂时固定?
另外注意:用户需要下载的数据为平均500kb到2MB,zip格式包含多个PDF文件
更新: 经过几个小时的调查,我发现这个 Web 应用程序使用不同的方法来下载,有些是使用 Http.Response 像上面的代码,有些是使用 FileContentResult 作为返回值。但两者都在客户端使用 jquery.FileDownload。我还在这个应用程序中具有下载文件方法的几个控制器中找到了这个方法,
private void CheckAndHandleFileResult(ActionExecutedContext filterContext)
{
var httpContext = filterContext.HttpContext;
var response = httpContext.Response;
if (filterContext.Result is FileContentResult)
{
//jquery.fileDownload uses this cookie to determine that
//a file download has completed successfully
response.AppendCookie(new HttpCookie(CookieName, "true")
{ Path = CookiePath });
}
else
{
//ensure that the cookie is removed in case someone did
//a file download without using jquery.fileDownload
if (httpContext.Request.Cookies[CookieName] != null)
{
response.AppendCookie(new HttpCookie(CookieName, "true")
{ Expires = DateTime.Now.AddYears(-1), Path = CookiePath });
}
}
}
实际上我不确定该方法是否与此错误相关,但它是在覆盖 System.Web.MVC.Controller OnActionExecuted 的方法中调用的,它包含该行如果使用 FileContentResult 则为文件下载添加 Cookie,如果不使用 FileContentResult 并且文件下载 Cookie 存在,则删除 Cookie。如果 Cookie 在创建后不小心被删除/清除,可能吗?而且由于每天有近百个用户频繁调用下载方法,有可能是Cookie堆积导致IIS Worker Process Crash?
我还检查了一些关于 Cookie 及其与 IIS 会话状态(我的应用程序使用 In-Proc 状态)的关系的参考资料。我关闭了吗?还是我错过了什么?
【问题讨论】:
-
如何将文件加载到内存中?你使用的是什么版本的 MVC?您描述的症状可能是内存泄漏。
-
需要下载的文件是直接在web应用程序中创建的,我们使用的MVC是MVC 4,如果有内存泄漏,哪里可以监控呢?因为我们已经从任务管理器中监控了,但是没有明显的内存使用,我们也尝试监控 IIS 应用程序池的虚拟和物理内存,此时物理内存在 700MB 左右,而虚拟内存在 1.5GB 左右跨度>
-
下载时是否在浏览器或客户端看到请求的错误代码?
-
您使用什么软件来创建 PDF 文件,是否有机会发布您正在使用的代码或产品/包的示例?
-
@Arathy 不,没有错误消息,也没有任何 http 状态,除了 200。我使用的 jquery.Filedownload 也没有抛出任何错误。
标签: c# asp.net asp.net-mvc asp.net-mvc-4 iis