Внутрипроцессный хостинг на .NET Core 2.2 замедлил время отклика API - PullRequest
0 голосов
/ 23 февраля 2019

Я недавно обновил веб-API .NET Core с 2.1 до 2.2.Microsoft утверждает, что новая модель хостинга InProcess должна быть в в 4 раза быстрее , чем модель хостинга OutOfProcess.

Однако, когда я устанавливаю модель хостинга IIS на InProcess <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> в .csproj, средний отклик API на 50-100 мс выше, чем при установке <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>.Любая идея, почему это замедляет время отклика API (более высокий пинг)?

Мой Startup.cs:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            IoCContainer.Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //Add proper cookie request to follow GDPR
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            //Add SendGrid email sender
            services.AddSendGridEmailSender();

            //Add general email template sender
            services.AddEmailTemplateSender();

            //Add ExcelFileDownloadService
            services.AddTransient<IExcelFileDownloadService, ExcelFileDownloadService>();
            //Add ExcelFileUploadService
            services.AddTransient<IExcelFileUploadService, ExcelFileUploadService>();
            //Add FileUploadService
            services.AddTransient<IUploadFileService, UploadFileService>();

            //CORS
            services.AddCors();

            //Add ApplicationDbContext to DI using MSSQL
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(IoCContainer.Configuration.GetConnectionString("AspifyConnection")));

            //Store keys to File System
            string path = Directory.GetCurrentDirectory() + @"\keys\";
            services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(path));


            //Add RepositoryWrapper to DI
            services.AddScoped<IRepositoryWrapper, RepositoryWrapper>();

            //Adds cookie based authentication
            //Adds classes like UserManager, SignInManager, PasswordHashers etc.
            services.AddIdentity<ApplicationUser, ApplicationRole>()
                .AddUserManager<UserManager<ApplicationUser>>()
                //Adds UserStore and RoleStore from this context
                .AddEntityFrameworkStores<ApplicationDbContext>()
                //Adds a provider that generates unique keys and hashes
                .AddDefaultTokenProviders();


            //Add JWT authentication for API clients
            var key = Encoding.ASCII.GetBytes(IoCContainer.Configuration["JwtSecretKey"]);
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("Administrator"));
            });

            //Change Identity Framework password policy
            services.Configure<IdentityOptions>(options =>
            {
                options.Password.RequireDigit = false;
                options.Password.RequiredLength = 5;
                options.Password.RequireLowercase = true;
                options.Password.RequireUppercase = false;
                options.Password.RequireNonAlphanumeric = false;
            });

            services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

            services.AddMvc(options =>
            {

            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
        {
            //Setup identity
            app.UseAuthentication();

            UpdateDatabase(app);

            //Allow all CORS
            app.UseCors(x => x
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials());

            app.UseDeveloperExceptionPage();

            //Force non-essential cookies to only store if the user has consented
            app.UseCookiePolicy();

            //Enable static files in wwwroot folder
            app.UseStaticFiles();

            //set HTTP routes
            app.UseMvc(routes =>
            {

                //Api route
                routes.MapRoute(
                name: "api",
                template: "api/{controller}/{action}/{moreInfo?}");

                //Default route to React
                routes.MapRoute(
                    name: "default",
                    template: "{*path}",
                    defaults: new { controller = "Home", action = "Index" });
            });
        }

        private static void UpdateDatabase(IApplicationBuilder app)
        {
            using (var serviceScope = app.ApplicationServices
                .GetRequiredService<IServiceScopeFactory>()
                .CreateScope())
            {
                using (var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>())
                {
                    context.Database.EnsureCreated();
                }
            }
        }
    }

.csproj:

 <Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <RuntimeFrameworkVersion>2.2.0</RuntimeFrameworkVersion>
    <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
    <OutputType>Exe</OutputType>
  </PropertyGroup>
  <ItemGroup>
    <Compile Remove="Migrations\20181110121254_rentalInfoLeasingTypeSetNull.cs" />
    <Compile Remove="Migrations\20181110121254_rentalInfoLeasingTypeSetNull.Designer.cs" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="EPPlus.Core" Version="1.5.4" />
    <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="2.2.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" />
    <PackageReference Include="Sendgrid" Version="9.10.0" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="wwwroot\Examples\" />
    <Folder Include="wwwroot\Uploads\" />
    <Folder Include="wwwroot\EmailTemplates\" />
    <Folder Include="wwwroot\React" />
    <Folder Include="wwwroot\React\media" />
  </ItemGroup>
  <ItemGroup>
    <None Include="Views\Home\Index.cshtml" />
  </ItemGroup>
  <ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JSONSchema="" /></VisualStudio></ProjectExtensions>
</Project>

CompaniesController.cs:

    /// <summary>
    /// Get list of all companies without their domains
    /// </summary>
    /// <returns>List of companies</returns>
    [Authorize(Roles = "Admin")]
    [HttpGet]
    public async Task<IActionResult> Get()
    {
        List<Company> companies = await _repoWrapper.Companies.GetAllAsync();
        List<CompanyListItemResponse> response = new List<CompanyListItemResponse>();

        foreach (Company company in companies)
        {
            response.Add(new CompanyListItemResponse { Id = company.Id, Name = company.Name });
        }

        response = response.OrderBy(x => x.Name).ToList();

        return Ok(response);
    }
...