C# 是否可以从ASP.NET核心控制器触发3000个并行异步HTTP请求?
我有一个web API控制器,它从前端接收过滤器对象 过滤器基本上只是一个包含过滤条件的json对象数组 现在,基于该过滤器,我必须对azure API(azure日志分析API)运行查询 此代码段对此进行了说明:C# 是否可以从ASP.NET核心控制器触发3000个并行异步HTTP请求?,c#,azure,asynchronous,asp.net-core,task-parallel-library,C#,Azure,Asynchronous,Asp.net Core,Task Parallel Library,我有一个web API控制器,它从前端接收过滤器对象 过滤器基本上只是一个包含过滤条件的json对象数组 现在,基于该过滤器,我必须对azure API(azure日志分析API)运行查询 此代码段对此进行了说明: var tasks = filters.Select(filter=> { try { return service.GetPerformanceC
var tasks = filters.Select(filter=>
{
try
{
return service.GetPerformanceCounters(filter.SComputerId, filter.WorkSpace);
}
catch (Exception ex)
{
return Task.Run(() => new List<Metrics>());
}
})
.ToList();
var metrics = (await Task.WhenAll(tasks))
.SelectMany(metric => metric)
.ToList();
var tasks=filters.选择(filter=>
{
尝试
{
return service.GetPerformanceCounters(filter.scocomputerrid、filter.WorkSpace);
}
捕获(例外情况除外)
{
返回任务。运行(()=>newlist());
}
})
.ToList();
var度量=(等待任务.WhenAll(任务))
.SelectMany(metric=>metric)
.ToList();
这基本上意味着,如果我有3000个filter对象,我必须运行3000个异步并行请求
但是当我在100个filter对象上测试这段代码时,异步并行任务失败了
我在调试面板中遇到以下异常:
引发异常:Azure.DAL.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:Azure.DAL.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:Azure.DAL.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:Azure.DAL.dll中的“System.Net.Http.HttpRequestException”
引发异常:Azure.DAL.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
引发异常:System.Private.CoreLib.dll中的“System.Net.Http.HttpRequestException”
线程0x3eac已退出,代码为0(0x0)。
线程0x2294已退出,代码为0(0x0)。
线程0x66b0已退出,代码为0(0x0)。
线程0x6958已退出,代码为0(0x0)。
线程0xb5c已退出,代码为0(0x0)。
线程0x6a98已退出,代码为0(0x0)。
线程0x16e8已退出,代码为0(0x0)。
线程0x28f8已退出,代码为0(0x0)
如何能够运行100多个异步HTTP请求而不出现此问题,我无法控制从前端发送的筛选器数量,但我需要能够运行与筛选器数量相等的并行异步操作
编辑:包含官方请求的端点文档。
该文件指出:
使用API密钥身份验证对数据进行采样,限制规则如下
按客户端IP地址应用。每个客户端IP地址都能够
每30秒最多200个请求,每天呼叫总数不设上限
编辑:GetPerformanceCounters实现。
public异步任务GetPerformanceCounters(字符串sourceComputerId、字符串workspaceId)
{
Debug.WriteLine(“启动新任务”);
//日志分析查询
变量查询=$@“性能
|其中SourceComputerId=='{SourceComputerId}'
|按SourceComputerId汇总arg_max(TimeGenerated,*)”;
var response=await RemoteKustoProvider.RunWorkSpaceQueryAsync
(
工作空间:工作空间ID,
查询:查询
);
Debug.WriteLine(“任务完成”);
//将查询发送到Kusto引擎。
返回JsonConvert.DeserializeObject
(
响应
);
}
提前感谢您帮助我解决此问题。这里有许多问题。首先,您需要意识到所有活动的工作都需要一个线程。这些线程来自线程池,通常设置为1000开箱即用。这意味着从一开始,你就在用这么多的任务耗尽线程池,所以可能有2000个任务在排队。异步有帮助,但它不是魔术。一旦请求发出,一些线程可能最终返回池,但线程切换不能保证。无论如何,线程池的耗尽速度仍然快于填充速度
那么,现在还不清楚这里到底发生了什么,因为有多个层面,你一次给我们喂一层。您发布了GetPerformanceCounters
的功能,但现在还不清楚RemoteKustoProvider.RunWorkSpaceQueryAsync
的功能。在某些时候,为了最终向Azure发出请求,您正在使用类似于HttpClient
的东西。根据您是如何做到这一点的(坦率地说,基于这段代码的质量,我不太希望您做得正确),您可能也会耗尽连接池。这是一个更为有限的资源,因此这意味着您的吞吐量大大降低,导致链上的进一步备份
接下来,即使您可以一次发出所有3000个请求,这实际上相当于对接收方服务器的DDoS攻击。如果你真的被t上的防火墙阻止了,我一点也不会感到惊讶
public async Task<List<Entities.Metrics>> GetPerformanceCounters(string sourceComputerId, string workspaceId)
{
Debug.WriteLine("New Task lauched");
// The log analytics query
var query = $@"Perf
| where SourceComputerId == '{sourceComputerId}'
| summarize arg_max(TimeGenerated, *) by SourceComputerId";
var response = await RemoteKustoProvider.RunWorkSpaceQueryAsync
(
workspace: workspaceId,
query: query
);
Debug.WriteLine("Task Finished");
// Send query to the Kusto-Engine.
return JsonConvert.DeserializeObject<List<Entities.Metrics>>
(
response
);
}