我有一个异步发送 500 个 HTTP 请求的应用程序。所有请求均已处理after由于 HTTP 客户端超时,15 秒失败,even当请求的端点已返回 200 OK 时。
代码非常简单。这里我们获取一大块请求(500),并异步执行它们。应该注意的是,下面的函数是在基于消耗的计划上运行的 Azure 函数。
public async Task RunBatch(List<Request> requests)
{
if (requests != null && requests .Count > 0)
{
var tasks = new Task[requests.Count];
var i = 0;
foreach (var request in requests)
{
var request = new HttpRequestMessage(HttpMethod.Post, new Uri(request.Url));
request.Content = new StringContent(request.BodyString, Encoding.UTF8, "application/json");
tasks[i] = _httpClient.SendAsync(request);
i++;
}
await Task.WhenAll(tasks);
}
}
我的构造函数中存在以下代码
_httpClient = new HttpClient();
_httpClient.Timeout = new TimeSpan(0, 0, 15); // 15 seconds
以下是来自 Azure 的日志。
我希望每个请求都有 15 秒的超时时间。但是,每当我的服务器开始处理等待的请求时,我都需要它给我一个准确的响应代码。这可能吗?
我应该注意:使用较高的 Http 超时(1 分钟),所有请求都会成功。
就我个人而言,我认为尝试发出 500 个并发请求总是容易出错。您提到您正在异步执行此操作,但实际上,当您启动 500 个“热门”任务然后等待它们全部完成时,您的代码中并没有太多异步性。
我会使用信号量来控制一次可以发出多少个请求。您可能需要玩弄数字才能找到最佳点。
以下代码在 LINQPad 中运行良好(尽管 bing 很快注意到奇数个请求并开始向页面添加验证码):
// using System.Threading;
async Task Main()
{
var httpClient = new HttpClient();
var urls = Enumerable.Range(1, 500).Select(e => "https://www.bing.com/").ToList();
// 10 concurrent requests - tweak this number
var semaphore = new SemaphoreSlim(10, 10);
var tasks = urls.Select(u => MakeRequest(u, semaphore, httpClient));
var allResponses = await Task.WhenAll(tasks);
// Do something with allResponses
}
private async Task<string> MakeRequest(string url, SemaphoreSlim semaphore, HttpClient httpClient)
{
try
{
await semaphore.WaitAsync();
var request = new HttpRequestMessage(HttpMethod.Get, new Uri(url));
var response = await httpClient.SendAsync(request);
// Add an optional delay for further throttling:
//await Task.Delay(TimeSpan.FromMilliseconds(100));
return await response.Content.ReadAsStringAsync();
}
finally
{
semaphore.Release();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)