Основной API Asp.net с CORS в Service Fabric 100% узкое место ЦП
У меня есть ASP.net Core на .Net Framework 4.5.2, размещенный в Service Fabric в качестве службы STATELESS.
API является ванильным API, пустым
[Route("Test")]
public class TestController : Controller
{
[HttpGet]
public IActionResult Get()
{
return Ok("Done");
}
}
Это мой код запуска
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();
}
}
Это метод 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);
}
Все просто и ясно, никаких настроек. Вызов CORS работает, все идеально. Я провел тестирование с использованием Visual Studio Team Services с нагрузкой 15K пользователей, и все это работало как шарм, с 14K RPS. Я думаю, что нагрузочный тест от VS, кстати, не использует промежуточное ПО CORS.
Теперь проблема в том, что когда я запускаю этот совершенно пустой API в производство, получая вызовы от почти 100 одновременных пользователей, процессор за 3 минуты подскочил до 100%. На вызовы отвечают, пока ЦП не достигнет 100%, а затем начнут отправлять ошибки обратно. Кажется, что с 15000 пользователей и без CORS все работает, а с 100 пользователями + CORS НЕ РАБОТАЕТ, ЦП переходит на 100% и остается таким до тех пор, пока я не перезагружу набор VM Scale.
Если я перестану отправлять вызовы, центральный процессор из 5 узлов останется стабильным на 99%, не принимая ни одного звонка.
Как это возможно? Я перепробовал все, проект прост и понятен, нагрузочный тест VS работает, только когда я ставлю это на реальные вызовы CORS с разных сайтов и разных IP-адресов, это происходит.
Я сделал трассировку производительности на сервере, прежде чем отправлять на него трафик, опять же с нагрузочным тестом из Visual Studio, использующим ТОЧНО заголовки CORS, все работает быстро.
С реальными звонками это то, что я вижу в профилировщике:
В этом нет ничего, кроме промежуточного программного обеспечения CORS и обычных процессов Kestrel. Служба без сохранения состояния съедает 99% процессорного времени и сохраняет его, даже если я ОСТАНОВЛЮ трафик.
Это еще одна 30-секундная трассировка без трафика, но процессор на 90%
Я не знаю, что еще делать, с CORS что-то не так, я в этом уверен, даже если он работает, что-то не так.
Это вызов CORS, правильно обслуженный.
Есть ли ошибка в промежуточном программном обеспечении Asp.net Core CORS?
ОБНОВИТЬ:
Я пробовал много комбинаций, чтобы изолировать проблему:
Новый кластер, тот же Asp.net Core vanilla service=> Проблема все еще существует
Тот же кластер, новый проект, тот же Asp.net Core vanilla service=> Проблема все еще существует
Тот же кластерный сервис WebAPI OWIN, тот же код => Проблема VANISHED!
Проблема возникает с Asp.Net Core в Service Fabric, использующей CORS с более чем 50 одновременными запросами.
Это ЦП (0,85%) с сервисом Asp.Net Stateless, использующий шаблон Visual Studio, OWIN и CORS, с примерно 100 одновременными соединениями и тем же пустым веб-API, описанным выше.
На данный момент мне нужна помощь из официального источника Microsoft для решения этой проблемы. Я почти уверен, что это ошибка Asp.net Core CORS, которая возникает, когда вы размещаете ее в Service Fabric в качестве службы без сохранения состояния и отправляете ей минимальный трафик (а не просто пару обновлений в браузере).