【发布时间】:2015-06-30 05:57:37
【问题描述】:
我在 Azure ML 中创建了一个简单的实验,并使用 http 客户端触发它。在 Azure ML 工作区中,执行时一切正常。但是,当我使用 http 客户端触发实验时,实验会超时并失败。为 http 客户端设置超时值似乎不起作用。
有什么办法可以设置这个超时值,让实验不会失败?
【问题讨论】:
标签: c# azure azure-machine-learning-studio
我在 Azure ML 中创建了一个简单的实验,并使用 http 客户端触发它。在 Azure ML 工作区中,执行时一切正常。但是,当我使用 http 客户端触发实验时,实验会超时并失败。为 http 客户端设置超时值似乎不起作用。
有什么办法可以设置这个超时值,让实验不会失败?
【问题讨论】:
标签: c# azure azure-machine-learning-studio
确保您正确设置了客户端超时值。如果为 Web 服务供电的服务器超时,那么它将返回一个带有 HTTP 状态代码 504 BackendScoreTimeout(或者可能是 409 GatewayTimeout)的响应。但是,如果您根本没有收到响应,那么您的客户等待的时间不够长。
您可以通过在 ML Studio 中运行实验来节省大量时间。转到实验属性以了解它运行了多长时间,然后将大约两倍的时间作为超时值。
【讨论】:
408 RequestTimeout,即使将http客户端超时设置为1小时也不能解决问题,它会再次超时。
我在将 Azure ML 实验作为 Web 服务发布时遇到了类似的问题。大多数时候它运行正常,而有时它返回超时错误。问题是实验本身有 90 秒 的运行时间限制。因此,很可能您的实验的运行时间超过了此限制并返回超时错误。 hth
【讨论】:
似乎无法根据 a feature request that is still marked as "planned" as of 4/1/2018 设置此超时。
MSDN forums from 2017 的建议是使用 Batch Execution Service,它会启动机器学习实验,然后异步询问是否完成。
这是来自 Azure ML Web 服务管理示例代码的代码 sn-p(所有 cmets 都来自他们的示例代码):
using (HttpClient client = new HttpClient())
{
var request = new BatchExecutionRequest()
{
Outputs = new Dictionary<string, AzureBlobDataReference> () {
{
"output",
new AzureBlobDataReference()
{
ConnectionString = storageConnectionString,
RelativeLocation = string.Format("{0}/outputresults.file_extension", StorageContainerName) /*Replace this with the location you would like to use for your output file, and valid file extension (usually .csv for scoring results, or .ilearner for trained models)*/
}
},
},
GlobalParameters = new Dictionary<string, string>() {
}
};
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
// WARNING: The 'await' statement below can result in a deadlock
// if you are calling this code from the UI thread of an ASP.Net application.
// One way to address this would be to call ConfigureAwait(false)
// so that the execution does not attempt to resume on the original context.
// For instance, replace code such as:
// result = await DoSomeTask()
// with the following:
// result = await DoSomeTask().ConfigureAwait(false)
Console.WriteLine("Submitting the job...");
// submit the job
var response = await client.PostAsJsonAsync(BaseUrl + "?api-version=2.0", request);
if (!response.IsSuccessStatusCode)
{
await WriteFailedResponse(response);
return;
}
string jobId = await response.Content.ReadAsAsync<string>();
Console.WriteLine(string.Format("Job ID: {0}", jobId));
// start the job
Console.WriteLine("Starting the job...");
response = await client.PostAsync(BaseUrl + "/" + jobId + "/start?api-version=2.0", null);
if (!response.IsSuccessStatusCode)
{
await WriteFailedResponse(response);
return;
}
string jobLocation = BaseUrl + "/" + jobId + "?api-version=2.0";
Stopwatch watch = Stopwatch.StartNew();
bool done = false;
while (!done)
{
Console.WriteLine("Checking the job status...");
response = await client.GetAsync(jobLocation);
if (!response.IsSuccessStatusCode)
{
await WriteFailedResponse(response);
return;
}
BatchScoreStatus status = await response.Content.ReadAsAsync<BatchScoreStatus>();
if (watch.ElapsedMilliseconds > TimeOutInMilliseconds)
{
done = true;
Console.WriteLine(string.Format("Timed out. Deleting job {0} ...", jobId));
await client.DeleteAsync(jobLocation);
}
switch (status.StatusCode) {
case BatchScoreStatusCode.NotStarted:
Console.WriteLine(string.Format("Job {0} not yet started...", jobId));
break;
case BatchScoreStatusCode.Running:
Console.WriteLine(string.Format("Job {0} running...", jobId));
break;
case BatchScoreStatusCode.Failed:
Console.WriteLine(string.Format("Job {0} failed!", jobId));
Console.WriteLine(string.Format("Error details: {0}", status.Details));
done = true;
break;
case BatchScoreStatusCode.Cancelled:
Console.WriteLine(string.Format("Job {0} cancelled!", jobId));
done = true;
break;
case BatchScoreStatusCode.Finished:
done = true;
Console.WriteLine(string.Format("Job {0} finished!", jobId));
ProcessResults(status);
break;
}
if (!done) {
Thread.Sleep(1000); // Wait one second
}
}
}
【讨论】: