3

我们最近开发了一个新的 ASP.NET MVC 4 Web 应用程序 (C#/Visual Studio)。经过本地测试和调试后,我们将其部署到生产环境中,然后开始收到越来越多的健康监控邮件。这些有不同的异常消息:

  • 堆栈空。
  • 收藏已修改;枚举操作可能无法执行。
  • 项目已添加。字典中的键:'ALL_HTTP' 正在添加的键:'ALL_HTTP'(还提到了其他键)。
  • 值不在预期范围内。

例如,我们无法简单解决或重现的一系列错误类型。'Stack Empty' 是发生最多的一个,每天有 100 次(例如,对于 1-10% 的用户),所以我们专注于这个,因为其他错误似乎相关。这是部分堆栈跟踪:

Exception information:
Exception type: System.InvalidOperationException
Exception message: Stack empty.
...
Stack trace:    at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.Stack`1.Pop()
at System.Web.WebPages.TemplateStack.Pop(HttpContextBase httpContext)

如图所示,堆栈跟踪大部分完全位于 MVC 框架 (System.Web) 中。在我们自己的代码中,经常出现在某些堆栈跟踪中的唯一位置是请求 URL 的视图(.cshtml 文件),然后是 @Html.RenderAction() 调用。到目前为止,我们已经将其中很多重构为 RenderPartial() 调用。这导致堆栈跟踪中没有更多视图,尽管一些 RenderPartial 现在也给出了一些

搜索此错误表明并发/并行执行是原因。这符合我们最初无法在本地重现错误的事实,但它确实发生在生产中。我们没有进行负载测试,但现在已经能够通过同时启动大量应用程序/请求在本地开发人员系统上重现错误。然而,在我们的代码中,没有任何事情是通过显式并行指令完成的。

这似乎与 MVC 视图不是线程安全的有关。然而,很难想象没有其他人会遇到这种情况。我们每天有几千名访客,任何时候大约有 30 多个活跃用户。遗憾的是,由于谷歌排名下降(与此问题相关),这个数字现在正在下降。

有谁知道这个问题的解决方案/方法?

4

2 回答 2

3

我正在开发一个 ASP.NET MVC 4 应用程序,我也遇到了你提到的错误。尽管它们不同,但它们似乎具有相同的来源。在花了几个小时试图找出原因(以及大量代码更改)之后,我从头开始分析。

由于我使用的是自定义路由,并且该路由有一个处理程序,它检查几件事并访问我通过评论数据库访问开始的数据库。非常快速地打开几个浏览器选项卡(使用 IISExpress > 显示所有应用程序窗口或通过 Ctrl+单击链接)我很高兴看到所有页面都正确显示,而不是几个随机错误消息。尝试了几次以确定并得出结论,访问数据库时出现问题。

public class MyNewRouteHandler : IRouteHandler {

    IHttpHandler MvcHandler;

    public IHttpHandler GetHttpHandler(RequestContext requestContext) {
        MvcHandler = new MvcHandler(requestContext);

        // some checkings and
        // some database access code 
        // that was commented

        return MvcHandler;
    }
}

有同事建议我在这个方法里面加了一个小线程睡眠:GetHttpHandler. 该行使错误再次出现,表明该问题与 DB 无关...当我这样做时,我看到该MvcHandler对象被定义为类属性,这可能是并发问题的根源(仅当执行多个几乎连续的访问时,才会显示问题)。将对象移动MvcHandler到方法内的本地对象。

public class MyNewRouteHandler : IRouteHandler {

    public IHttpHandler GetHttpHandler(RequestContext requestContext) {
        IHttpHandler MvcHandler = new MvcHandler(requestContext);

        // some checkings and
        // some database access code 
        // that was commented

        return MvcHandler;
    }
}

并且经过测试,没有更多的错误。取消注释我所有访问数据库的代码(并进行了其他检查),但仍然没有发现更多错误。差不多3天过去了,一切仍然正常。

于 2012-12-11T16:59:42.693 回答
0

这种做法Custom Route Handler确实解决了我的大部分错误,但我还有一些错误和新消息。其中一个指向我的代码行,Custom Route Handler所有这些都有一个共同点,即字典正在由 MVC 框架处理,所以......我还有并发问题吗?

我假设是这样,并且我的所有方法属性都被移动到了public IHttpHandler GetHttpHandler(RequestContext requestContext)方法中,而不仅仅是前面提到的那个。其中之一是RouteData集合......最后,经过 2 天,似乎没有更多错误出现。

于 2012-12-19T09:07:29.587 回答