并行进行 http 调用时出现未经授权的响应
Unauthorized response when making http calls in parallel
我有代码循环访问一些服务并为这些服务调用 api。如果我一次 运行 这些调用,我会得到每个调用的响应 StatusCode
OK (200)。如果我将代码并行更改为 运行,则第一个调用完成后会得到一个 OK,但其余调用都将完成 StatusCode
值 Unauthorized (401)。
奇怪的是,所有调用实际上都是在服务器上处理的——即使是我收到未经授权响应的调用。我不明白发生了什么。
这是我运行宁的代码。 (并行代码目前已被注释掉)
using (HttpClientHandler handler = new HttpClientHandler())
{
handler.UseDefaultCredentials = true; // Use Windows Credentials
using (var client = new HttpClient(handler))
{
//Some services can run up to 1.5 minutes - need to ensure we don't time out
client.Timeout = new TimeSpan(0, 3, 0);
//Get Available Services
Console.WriteLine("Retrieving service list ...");
var result = await client.GetStringAsync(_baseURL);
var jss = new JavaScriptSerializer();
List<Service> services = new List<Service>();
services = jss.Deserialize<List<Service>>(result);
Console.WriteLine(services.Count.ToString() + " services to run.");
// ** Non Parallel Code **
foreach(var service in services)
{
Console.WriteLine("Running " + service.Name);
var _serviceResponse = await client.PostAsync(_baseURL + "/" + service.Id.ToString() + "/run", null);
Console.WriteLine(service.Name + ": Response = " + _serviceResponse.StatusCode + " " + _serviceResponse.ReasonPhrase);
}
// ** Parallel Code **
//await Task.WhenAll(services.Select(async s => {
// Console.WriteLine("Running " + s.Name);
// var _serviceResponse = await client.PostAsync(_baseURL + "/" + s.Id.ToString() + "/run", null);
// Console.WriteLine(s.Name + ": Response = " + _serviceResponse.StatusCode + " " + _serviceResponse.ReasonPhrase);
//}));
}
}
}
根据我的阅读,HttpClient
在使用 Async(我正在做的)时应该能够毫无问题地处理同时调用。所以我很好奇为什么这段代码的行为不同。
服务器是否可能对来自同一 IP/User 的客户端请求应用某种速率限制,并在超过最大值时返回 401?
原来我调用的服务不喜欢那么快收到那么多请求。
我不得不先上传在线列表,然后使用我的代码只上传少量的添加或删除内容。
我有代码循环访问一些服务并为这些服务调用 api。如果我一次 运行 这些调用,我会得到每个调用的响应 StatusCode
OK (200)。如果我将代码并行更改为 运行,则第一个调用完成后会得到一个 OK,但其余调用都将完成 StatusCode
值 Unauthorized (401)。
奇怪的是,所有调用实际上都是在服务器上处理的——即使是我收到未经授权响应的调用。我不明白发生了什么。
这是我运行宁的代码。 (并行代码目前已被注释掉)
using (HttpClientHandler handler = new HttpClientHandler())
{
handler.UseDefaultCredentials = true; // Use Windows Credentials
using (var client = new HttpClient(handler))
{
//Some services can run up to 1.5 minutes - need to ensure we don't time out
client.Timeout = new TimeSpan(0, 3, 0);
//Get Available Services
Console.WriteLine("Retrieving service list ...");
var result = await client.GetStringAsync(_baseURL);
var jss = new JavaScriptSerializer();
List<Service> services = new List<Service>();
services = jss.Deserialize<List<Service>>(result);
Console.WriteLine(services.Count.ToString() + " services to run.");
// ** Non Parallel Code **
foreach(var service in services)
{
Console.WriteLine("Running " + service.Name);
var _serviceResponse = await client.PostAsync(_baseURL + "/" + service.Id.ToString() + "/run", null);
Console.WriteLine(service.Name + ": Response = " + _serviceResponse.StatusCode + " " + _serviceResponse.ReasonPhrase);
}
// ** Parallel Code **
//await Task.WhenAll(services.Select(async s => {
// Console.WriteLine("Running " + s.Name);
// var _serviceResponse = await client.PostAsync(_baseURL + "/" + s.Id.ToString() + "/run", null);
// Console.WriteLine(s.Name + ": Response = " + _serviceResponse.StatusCode + " " + _serviceResponse.ReasonPhrase);
//}));
}
}
}
根据我的阅读,HttpClient
在使用 Async(我正在做的)时应该能够毫无问题地处理同时调用。所以我很好奇为什么这段代码的行为不同。
服务器是否可能对来自同一 IP/User 的客户端请求应用某种速率限制,并在超过最大值时返回 401?
原来我调用的服务不喜欢那么快收到那么多请求。
我不得不先上传在线列表,然后使用我的代码只上传少量的添加或删除内容。