据我记得,角色实例应该在崩溃/失败后自动执行重启。为了测试这种行为,我编写了一个应用程序来强制执行内存不足异常并且我的应用程序崩溃了。角色实例没有执行重新启动,因为它仍在运行并且正常 - 实例只是重新启动 .NET 运行时。
我试图找出实例对不同错误的反应。就我而言,不需要重新启动。什么类型的错误/异常(我可以强制执行)会导致实例完全重启?什么类型的错误/异常会永远杀死一个实例?
导致角色实例被回收(重新启动)的唯一原因是RoleEntryPoint的Run方法退出时。这通常发生在您:
但是,当您启用 IntelliTrace 日志收集时,您的角色会循环使用,而是挂起。
WebRole 的默认模板不会覆盖Run()方法,因此保留了默认实现,即“Thread.Sleep(-1);”。没有(自动)事件会导致 WebRole 的自动角色回收。除非您在 RoleEntryPoint 中执行某些操作,否则会导致 Run 方法退出。这种自动回收只发生在 WorkerRole 中,它实现了 Run() 方法。
更新1(根据评论1)
run-Methoded of a RoleEntryPoint faces an error
不只是一个错误,而是这样一种错误(即未处理的异常),它会导致 Run() 方法退出。
此外,您不能只覆盖 WebRole 中的 Run(),因为您的 RoleEntryPoint 后代生活在与您的 Web 应用程序不同的应用程序域(甚至不同的进程)中(因此它不知道您的应用程序的异常)。在此处阅读有关完整 IIS 托管和进程的更多信息。
因此,对于 Web 角色,您只需拥有一个具有 IIS 7.0 / 7.5 功能的 Web 应用程序,它不知道此 IIS 是 Azure 部署的一部分。Global.asax 是您管理 ASP.NET 中未处理的 Web 应用程序错误的地方。查看这个问题,其答案为 Application_Error() 处理程序提供了一个很好的示例。
您可以使用 RoleEnvironment 类型的RequestRecycle静态方法在 Application_Error() 方法中手动要求角色回收。但是不建议您这样做。由于应用程序错误,我没有看到重新启动 Web 服务器的好习惯。您应该实施良好的异常处理和错误记录策略,定期检查您的错误日志并采取措施避免需要重新启动服务器的严重错误。
你的初衷是什么?要了解角色何时会被自动回收,或者为您的应用程序建模,例如在错误时自动回收您的角色?如果是后者,我建议您修改您的业务需求/逻辑。
更新 2
我不能从 Neil 的口中说出来,但“实例故障”是可能导致正在运行的 VM 挂起的所有内容。Windows Azure 中的实例是托管应用程序代码的单一虚拟机(阅读此博客文章有关托管服务、角色、实例的详细说明)。您的应用程序在基于 Windows Server 的操作系统中运行。它是一个虚拟机。任何事情都可能发生——从主机上的硬件故障到客户操作系统的通用软件/驱动程序故障。不必成为您的代码。因此,如果发生会导致单个 VM 失败的事情 - 此问题将由 Windows Azure Fabric 自动处理。如果有必要 - 您的代码会自动部署到另一个虚拟机。这是自动发生的。你什么都不做。想象一下 HDD 损坏、内存模块烧毁或网络接口停止响应 - 这些只是可能导致正在运行的 VM 失败的几个简单问题。这是一个实例失败。
您应该注意代码中的故障。其他一切 - Windows Azure Fabric 控制器负责处理。
更新 3
- 如果发生异常并且未处理,webrole 中的 asp.net 应用程序会发生什么?在我寻找它之前,应用程序会一直处于未定义状态(“损坏”),还是会被 vm 终止?
这个问题完全超出范围!共享主机帐户中的 asp.net 应用程序会发生什么?还是在本地 IIS 安装中?其操作导致崩溃的用户的应用程序崩溃。最坏情况下的应用程序池回收。我从未见过“挂起”的 asp.net 应用程序。没有“终止的 asp.net 应用程序”或“损坏”之类的东西。如果它是在应用程序启动或第一次请求期间引起的一般错误 - 应用程序将永远不会在线。如果它是由某些用户操作序列引起的错误 - 用户将看到一条丑陋的错误消息,仅此而已(除非您的 Global.asax 中有适当的 Application_Error() 处理程序。我认为这足以解释一个无关紧要的问题与 Azure。
- 您能想到我的应用程序中的一段 .NET 代码可能导致整个 Web 角色崩溃,或者托管代码不可能(除了 .NET 中的未知错误)?
你在开玩笑吗?此代码将使您的网络角色崩溃并强制回收:
RoleEnvironment.RequestRecycle()
请接受这个问题,因为我认为没有遗漏什么。此外,它还回答了至少 4 个问题,添加到原始问题中。
最终的
没有“永远杀死实例”这样的事情。