Основной 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, правильно обслуженный.

Cors Call

Есть ли ошибка в промежуточном программном обеспечении Asp.net Core CORS?

ОБНОВИТЬ:

Я пробовал много комбинаций, чтобы изолировать проблему:

  1. Новый кластер, тот же Asp.net Core vanilla service=> Проблема все еще существует

  2. Тот же кластер, новый проект, тот же Asp.net Core vanilla service=> Проблема все еще существует

  3. Тот же кластерный сервис WebAPI OWIN, тот же код => Проблема VANISHED!

Проблема возникает с Asp.Net Core в Service Fabric, использующей CORS с более чем 50 одновременными запросами.

Это ЦП (0,85%) с сервисом Asp.Net Stateless, использующий шаблон Visual Studio, OWIN и CORS, с примерно 100 одновременными соединениями и тем же пустым веб-API, описанным выше.

Owin

На данный момент мне нужна помощь из официального источника Microsoft для решения этой проблемы. Я почти уверен, что это ошибка Asp.net Core CORS, которая возникает, когда вы размещаете ее в Service Fabric в качестве службы без сохранения состояния и отправляете ей минимальный трафик (а не просто пару обновлений в браузере).

0 ответов