Azure云服务上的间歇性ASP.net IIS8.5无法捕获500内部服务器错误

时间:2014-08-08 10:24:41

标签: asp.net azure error-handling internal-server-error

让我们从一些背景信息开始。我正在运行一个非常简单的ASP.net MVC Azure云服务(一个Web角色,带有IIS 8.5的Windows Server 2012 R2)。此服务从Flash客户端接收统计信息,该客户端大约每10秒(对于可能非常大量的客户端)和JavaScript发布数据。所有服务包含一个控制器,其中包含两个简单的操作和一组参数(表示以各种组合发送的各个统计信息)。所有服务都设置了CORS和cookie响应(客户端/ JavaScript可以嵌入到随机域中),验证接收数据的完整性,然后将其存储到Azure表存储帐户中。

为了确保我们的服务以最佳方式运行,我们使用New Relic来跟踪服务性能,为了确保我们的数据准确(即我们成功记录所有收到的消息),我们实施了自定义错误处理解决方案,以便我们可以修复任何可能出现的问题/错误。

我们已经使用jmeter测试了我们的服务并且没有遇到任何问题,但是现在我们已经部署到实时环境并且我们的服务正在使用中,我们开始偶尔遇到500个内部服务器错误(大约5%的请求)。最大的问题是我们自己的错误处理代码没有检测到这些错误,但New Relic会报告某些请求产生500内部服务器错误(没有更多信息,如堆栈跟踪,有时有,有时没有报告参数)。

我们的自定义错误处理包含一个HTTP模块,它注册到AppDomain.CurrentDomain.UnhandledException和context.Error事件。从理论上讲,这应该是捕获(然后记录)我们自己的代码中尚未被捕获(和记录)的任何异常。相关的web.config部分按以下方式配置:

<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx">
  <error statusCode="404" redirect="~/404.aspx" />
  <error statusCode="500" redirect="~/500.aspx" />
</customErrors>

<httpErrors existingResponse="Replace">
  <clear />
  <error statusCode="404" path="404.html" responseMode="File" />
  <error statusCode="500" path="500.html" responseMode="File" />
</httpErrors>
<modules>
  <add type="namespace.UnhandledExceptionModule" name="UnhandledExceptionModule" preCondition="managedHandler" />
</modules>

但事实并非如此。我尝试打开各种日志记录,但IIS日志没用(它们只显示返回了500响应,但没有其他有用的信息)。我能够收集的唯一有用的信息来自失败的请求跟踪,但我无法确定该信息的实际问题是什么(谷歌搜索错误代码或异常导致没有具体的)。可以在此处找到失败跟踪的相关部分的屏幕截图:

http://i57.tinypic.com/20acrip.jpg

我还在这里上传了完整的跟踪:

http://pastebin.com/fDt3thvr

每个失败的请求都会生成完全相同的日志,因此我们看到的错误始终是由同一问题引起的。但是,我无法确定这个问题是什么,更不用说找到解决问题的方法了。即使我有错误代码和消息,谷歌搜索它们只会返回6年前修复过的问题的旧主题。

对于我们的业务而言,这些消息可以高度准确地记录,这一点非常重要,但就目前而言,我对如何获得有关这些服务器上发生的更多信息没有进一步的想法。我们也无法在受控环境中复制此行为。

此外,我们的错误记录本身也能正常工作。 &#39;正常&#39;错误按预期记录,我们还验证了HTTP模块实际工作。

编辑:

控制器伪代码如下:

[HttpPost]
public ActionResult Method(...)
{
    // Set cookie and CORS reponse, check for early out.
    if(earlyOut)
         return 404;

    // Store received values.
    azuretable.ExecuteAsync(TableOperation.InsertOrMerge(...));

    return 200;
}

EDIT2:

我花了一些时间分析失败的请求跟踪,它们似乎主要是由IE9的用户生成的。我实际上设法通过在加载时快速离开页面来重现错误2次,​​因为问题似乎是由于中止的Ajax调用(我们在页面加载期间充分利用)引起的。为什么中止的呼叫会导致500错误,而不是整齐地处理?

2 个答案:

答案 0 :(得分:0)

饼干超过4k吗?我们在IIS上发生了同样的事情,请求有时最终导致500内部服务器错误。这些错误几乎无法追踪。 我通过简单地在4093字节限制内膨胀cookie来重现这个问题。

答案 1 :(得分:0)

我认为这是因为您没有等待异步方法调用,或者您没有返回等待响应。当我忘记这样做时,我确实遇到了这个问题。

await azuretable.ExecuteAsync(TableOperation.InsertOrMerge(...))

然后你应该好。我想你会发现,在你的通话完成后,异步通话正在结束。