让我们考虑一个辅助角色:
- 承载 WCF 服务器
- 侦听几个 Azure 存储队列和服务总线队列
处理方法执行一些 Azure 存储 I/O,HttpClient
对外部 API 和实体框架调用的调用。现在,我希望我的辅助角色正常关闭,以便以托管方式完成或取消所有挂起的操作:
- 触发
RoleEntryPoint.OnStop()
后停止接受任何传入请求。Azure 能为我做吗?如果不是,我该如何执行? - 等待
N
秒以完成任何挂起的操作 N
秒后取消剩余的任何操作。取消不得超过M
秒,以便N + M < 5 minutes
.我相信 5 分钟是 Azure 运行时在触发OnStop()
后和终止进程之前等待的保证时间。
我把它想象成这样:
public override void Run() {
// create a cancellation token source
try {
// pass the token to all processing/listening routines
}
catch (Exception e) { }
}
public override void OnStop() {
try {
// trigger the cancellation token source
}
catch (Exception e) { }
}
上面的简单示例假定我的所有处理例程都是从上到下异步的(对 EF/HttpClient 调用)。如果这是要走的路,我需要一个处理前提条件(WCF 主机、队列侦听器)的工作示例。
打开的问题:
- 如何确保在触发
OnStop()
后不再向辅助角色发送传入的 TCP 请求?这对于将关机代码纳入 5 分钟限制非常重要。 - 考虑到配置文件中的WCF通道超时,EF超时等所有内容,如何找出
N
和M
的具体数字? - 同步代码甚至可能吗?
一旦触发 RoleEntryPoint.OnStop() 就停止接受任何传入的请求。Azure 能为我做吗?如果不是,我该如何执行?
正如这份官方文件提到的ServiceHost.close()
:
Close 方法允许在返回之前完成任何未完成的工作。例如,完成任何缓冲消息的发送。
若要正常终止接收新请求但允许现有连接继续的 WCF 服务,可以参考此问题。
对于侦听服务总线队列,可以定义一个CancellationTokenSource
对象,并在触发RoleEntryPoint.OnStop()
后调用CancellationTokenSource.Cancel()
。
并检查是否已请求取消CancellationTokenSource
,如下所示:
try
{
if (!_cancellationTokenSource.IsCancellationRequested)
{
//retrieve and process the message
}
}
catch (Exception)
{
// Handle any message processing specific exceptions here
}
允许 N 秒完成任何挂起的操作
根据我的理解,我假设您可以在调用CancellationTokenSource.Cancel()
并在OnStop
函数中终止 WCF 服务后调用Task.Delay(TimeSpan.FromSeconds(N)).Wait()
。然后,挂起的操作将被丢弃,同时关闭辅助角色实例。
考虑到配置文件中的 WCF 通道超时、EF 超时等所有内容,如何找出 N 和 M 的具体数字?
我假设你可以将应用程序见解与辅助角色结合使用来检索指标数据并为N
配置合理的值,以降低失败请求率,并快速让 VM 重新启动并开始处理新请求。还可以参考本教程,了解如何处理 Azure OnStop 事件。