C#—执行许多并发传出HTTP请求时出错

问题描述

我正在尝试执行25k +并发传出HTTP请求,这些请求在我的本地计算机上正确运行(运行Windows 10时具有8个内核和16个线程,并具有16GB RAM),但运行时超时/错误从运行Ubuntu 20.04.1 LTS(使用2vCPU和2GB RAM)的Digital Ocean液滴中提取。

这与C#中的.NET(dotnet)Core控制台应用程序一起使用。

  • 我的个人网络的下载速度为~300mbps
  • 液滴的下载速度为~1gbps

当将并发HTTP请求限制为5k(但尝试使用7.5k +时开始失败)而不是所需的〜25k时,Droplet作业可以正常工作。

据Digital Ocean团队告知我:

  • 液滴中没有最大并发HTTP并发请求。
  • 液滴中没有最大入站带宽限制。

Droplet上的响应时间更快,所以我期望相反的行为。

Droplet 中的CURL:

CURL from the Droplet

本地计算机中的CURL:

CURL from Local machine


该代码包括读取一个巨大的数据库并生成25,000个批次的批处理,并且每个批次同时发出请求,然后执行一些其他操作并更新这些条目。

请求代码:

public static class HttpUtils
{
  private static readonly HttpClient client = new HttpClient();

  public static async Task GetThing(string id)
  {
    try
    {
      var response = await client.GetAsync($"https://api.example.com/{id}");
      Console.WriteLine($"Success {id}");
    }
    catch (Exception ex)
    {
      Console.WriteLine($"Failed request {id}:\n{ex.Message}");
    }
  }
}

然后我执行批处理:

var tasks = batch.Select(thing => HttpUtils.GetThing(thing.id));
await Task.WhenAll(tasks);

这些错误在运行一段时间后出现:

[ERR] Failed request XXXXXXXXX
System.Threading.Tasks.TaskCanceledException: The operation was canceled.
   at System.Net.Http.ConnectHelper.ConnectAsync(String host,Int32 port,CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request,Boolean allowHttp2,CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request,CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request,CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request,Boolean doRequestAuth,CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask,HttpRequestMessage request,CancellationTokenSource cts,Boolean disposeCts)
   at collector_utils.HttpUtils.GetThing(String id) in /root/development/foo/bar/HttpUtils.cs:line 20

我尝试在HTTP响应成功后进行处理,但是它完全没有帮助,并且目前我还不知道可以尝试什么,也无法达到某种极限。 / p>

是否可能是因为我在Droplet中可用的线程较少并且正在排队处理数千个请求,所以超时计数器在队列时间开始,并最终使尚未处理的请求超时?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...