我正在构建一个 Azure Web 作业,该作业将数据从我的 blob 存储发布到在我的客户端环境中运行的其他(不是 azure)Web 服务。 此 http-POST 的处理可能需要很长时间(最多 30 分钟),这很好,因为没有用户在等待此过程完成。
经过一天的谷歌搜索和测试,我的测试看起来像这样。
- Webservice 有一个测试方法,该方法在等待 10 分钟后返回。
- Azure Web 作业将使用
System.Net.Http.HttpClient
调用测试方法,Timeout
设置为 11 分钟。 - 在父 Azure Web 应用中的"
ApplicationSettings
"下,Always On
设置为 true,应用设置WEBJOBS_IDLE_TIMEOUT
设置为3600
。 - 在 Azure Web 作业等待时,它将每秒执行
Console.WriteLine("Heartbeat")
(以解决空闲 CPU 时间)。
这将导致System.Threading.Tasks.TaskCanceledException: A task was canceled.
当我从Visual Studio运行相同的测试时,它将在等待10分钟后成功完成。
我错过了什么吗?这是怎么回事?
编辑:包括我的测试中的代码,以及异常和堆栈跟踪。
private static async Task<String> AzureWebJobTest()
{
var url = "[MyUrl]";
var json = new StringContent("[MyValidJSON]", Encoding.UTF8, "application/json");
var client = new HttpClient();
client.Timeout = TimeSpan.FromMinutes(11);
return await (await client.PostAsync(url, json)).Content.ReadAsStringAsync();
}
以及此函数引发的结果异常:
System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at [MyProjectNamespace].Program.<AzureWebJobTest>d__5.MoveNext() in [MyLocalPath]Program.cs:line 100
我怀疑请求的 230 秒超时限制会导致问题。正如David Ebbo在这个帖子中所说:
对于未发回任何数据的请求,有 230 秒(即略少于 4 分钟)的超时。之后,客户端会得到你看到的 500,即使实际上允许请求继续服务器端。
作为解决此问题的方法,我在Web服务上创建了一些请求管理。它跟踪使用System.ServiceModel.Dispatcher.IDispatchMessageInspector
开始和完成的每个请求。现在可以通过新的 Web 服务检索这些请求的状态。
结果:
Azure Web 作业启动持久请求,当请求超过 230 秒时,它将捕获超时异常,并使用新的 Web 服务继续检查原始(持久)请求的状态,直到完成。