RoleEnvironment.RequestRecycle() 未触发重新启动

本文关键字:重新启动 RequestRecycle RoleEnvironment | 更新日期: 2023-09-27 18:36:50

我们有一个具有多个实例的 Azure 云服务。这些实例可能会陷入致命状态,此时我们希望触发实例重启。

我们尝试过致电:

RoleEnvironment.RequestRecycle();

但根据 Azure 门户,实例继续保持启动和运行,没有任何重启迹象。

我们甚至试图通过发布以下命令将其置于错误状态:

Environment.FailFast("Failed.");

但这似乎也不会触发重启(同样,至少根据 Azure 门户)。

我们是否应该在 Azure 门户中看到这种情况,如果是这样,什么可能会阻止它重新启动?

更多详情

基本上,作为我们逻辑的一部分,我们正在旋转一个单独的线程来执行一些繁重的处理,并且此处理有一个超时,此时我们需要重新启动以终止线程并释放所有消耗的资源。我知道理想情况下我们会对线程进行更正确的处理并取消它,但此时这不是一个选择。所以我们只想重新启动。

简化版本如下所示:

var mainTask = Task.Run(() => DoHeavyProcessing());
var timeoutTask = Task.Delay(TimeSpan.FromMinutes(10));
if (Task.WaitAny(mainTask, timeoutTask) == 1)
{
    RoleEnvironment.RequestRecycle();
}

但同样,RequestRecycle()似乎并没有触发重启。

RoleEnvironment.RequestRecycle() 未触发重新启动

因此,我们对此进行了一些进一步的测试,发现 - 至少根据我们正在经历的情况 - RequestRecyle不会重新启动云服务 VM,而只是回收 VM 中的角色实例。

Environment.FailFast也是如此 - 它是回收角色实例,而不是完全重新启动。

因此,净效果是相同的,如果不是更好一点,因为这可能比完全重新启动快一点。

对于那些寻求完全重启的人(在我们的例子中不是必需的),可能需要进行 shell 关闭:

Process.Start("shutdown","/r /t 0");

我会向您的项目添加一个处理程序以捕获 OnStop 事件以检查是否正在请求回收。此外,如果您查看 MSDN 页面以获取 RequestRecycle,如果请求失败,它可能会引发异常,因此可能也会捕获并记录该异常。

我可以想象,如果你的底层代码真的破坏了计算资源,回收请求正在排队,可能需要一些时间才能触发。 因此,最好从实例外部控制此设置,并使用 Azure 服务器管理 API 强制重启实例。也许记录到队列,在定义的时间段后,如果实例/作业仍在记录,则杀死该实例。

请注意,长时间运行的密集型进程实际上可能会导致计划外的实例回收,因为 Azure Fabric 可能会将主机标记为不正常并重新启动它。