Fra*_*llo 6 azure-service-fabric asp.net-core asp.net-core-middleware asp.net-core-webapi
我在.Net Framework 4.5.2上有一个 ASP.net Core,作为无状态服务托管在 Service Fabric 上。
该 API 是一个普通 API,空的
[Route("Test")]
public class TestController : Controller
{
[HttpGet]
public IActionResult Get()
{
return Ok("Done");
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的启动代码
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddResponseCompression();
services.AddMvc().AddJsonOptions(opts =>
{
// Force Camel Case to JSON
opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors("CorsPolicy");
app.UseResponseCompression();
app.UseMvc();
}
}
Run Code Online (Sandbox Code Playgroud)
这是 OpenAsync 方法:
Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
{
var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(_endpointName);
string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}";
//.UseWebListener()
_webHost = new WebHostBuilder().UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseUrls(serverUrl)
.Build();
_webHost.Start();
return Task.FromResult(serverUrl);
}
Run Code Online (Sandbox Code Playgroud)
一切都简单明了,没有定制。CORS 调用有效,一切都很完美。我使用 Visual Studio Team Services 进行了一次测试,负载为 15K 用户,一切都非常顺利,RPS 为 14K。顺便说一句,我认为 VS 的负载测试不使用 CORS 中间件。
现在的问题是,当我将这个完全空的 API投入生产时,仅接收来自大约100 个并发用户的调用,CPU 在 3 分钟内跃升至 100%。呼叫会得到应答,直到 CPU 达到 100%,然后开始发回错误。似乎在 15000 个用户且没有 CORS 的情况下一切正常,而在 100 个用户 + CORS 不起作用的情况下,CPU 会达到 100%,并保持这种状态,直到我重新启动 VM 规模集。
如果我停止发送呼叫,5个节点的CPU保持稳定在99%,没有收到任何呼叫。
这怎么可能? 我尝试了一切,该项目简单明了,VS 负载测试有效,只有当我将其放在来自不同站点和不同 IP 地址的真实 CORS 调用上时,才会发生这种情况。
在向服务器发送流量之前,我在服务器中进行了性能跟踪,再次使用 Visual Studio 使用 CORS 标头进行负载测试,一切都非常快。
对于现实世界的调用,这是我在分析器中看到的:
除了 CORS 中间件和常用的 Kestrel 进程之外,什么都没有。无状态服务占用了 99% 的 CPU,即使我停止流量也会保留它。
这是另一个 30 秒的跟踪,没有流量到来,但 CPU 利用率为 90%
我不知道还能做什么,CORS 有问题,我确信,即使它有效,不知何故出了问题。
这是一个 CORS 调用,已正确处理。
Asp.net Core CORS 中间件是否存在错误?
更新:
我尝试了多种组合来隔离问题:
新集群,相同的 Asp.net Core vanilla 服务 => 问题仍然存在
相同的集群新项目相同的 Asp.net Core vanilla 服务 => 问题仍然存在
相同的 Cluster WebAPI OWIN 服务,相同的代码 =>问题消失了!
Service Fabric 上的 Asp.Net Core 使用 CORS 且并发请求超过 50 个时会出现此问题。
这是使用 Visual Studio 模板、OWIN 和 CORS 的 Asp.Net 无状态服务的 CPU (0.85%),具有大约 100 个并发连接和上面相同的空 Web API
此时我需要微软官方的帮助来解决这个问题。我几乎可以肯定这是一个Asp.net Core CORS 错误,当您将其作为无状态服务托管在 Service Fabric 上并向其发送一些最小流量(而不仅仅是浏览器中的几次刷新)时,就会发生这种情况。
归档时间: |
|
查看次数: |
1154 次 |
最近记录: |