Лазерные розетки?

У меня есть ASP.NET Core веб-сайт с большим количеством одновременных пользователей, который много раз падает в течение дня, и я увеличил масштаб, но не повезло. Мне сообщили, что мой многочисленный вспомогательный персонал Azure говорит, что проблема заключается в том, что я отправляю много запросов на базы данных, хотя использование баз данных улучшилось после создания индексов. Можете ли вы любезно сообщить, что вы думаете, проблема такая, как я сделал все возможное... Мне сказали, что у меня "утечки сокетов".

Обратите внимание:

  • У меня нет внешних вызовов службы, кроме sendgrid
  • Я не использовал ConfigureAwait (false)

  • Я не использую "использование" операторов или явно использую контексты

Это моя строка соединения. Если это может помочь...

Server=tcp:sarahah.database.windows.net,1433;Initial Catalog=SarahahDb;Persist Security Info=False;User ID=********;Password=******;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Max Pool Size=400;

Вот несколько примеров кода:

В Startup.CS:

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

Основной класс:

    private readonly ApplicationDbContext _context;

    public MessagesController(ApplicationDbContext context, IEmailSender emailSender, UserManager<ApplicationUser> userManager)
    {
        _context = context;
        _emailSender = emailSender;
        _userManager = userManager;
    }

Этот важный код метода, например:

       string UserId = _userManager.GetUserId(User);
        var user = await _context.Users.Where(u => u.Id.Equals(UserId)).Include(u => u.Messages).FirstOrDefaultAsync();
        // some other code
        return View(user.Messages);

Просьба посоветуйте, поскольку я старался изо всех сил, но это очень неловко для меня в шрифте моих клиентов.

Ответ 1

Без сообщений об ошибках, которые вы видите, вот несколько идей, которые вы можете проверить.

  • Я бы начал с перехода на ваш обзор веб-приложений на Azure Portal. Обновите график мониторинга до тех пор, пока у вас возникнут проблемы. Вы связаны с процессором? Вы исчерпали память? Также проверьте длину очереди HTTP. Если ваша очередь HTTP очень длинная, это связано с тем, что ваш сервер задыхается, пытаясь обслуживать запросы, и пользователи испытывают проблемы с таймаутом.

    • Затем перейдите на свой лезвие обзора SQL Server на портал Azure и просмотрите диаграмму использования ресурсов. Установите период времени на графике, если у вас возникли проблемы. Вы привязали свои DTU для своей базы данных? Если это так, это признак плохой индексации, плохой дизайн схемы, или вы просто недоразвиты и должны увеличиваться.

    • Включите ApplicationInsights, если вы еще этого не сделали. Вы можете использовать API ApplicationInsights, чтобы вставлять свои собственные инструкции трассировки в свой код. Или вы можете увидеть исключения, вызывающие проблему, без необходимости выполнять собственную трассировку.

    • Проверьте журналы Kudu для своих веб-приложений.

Я согласен с Tseng - ваше использование EF и .NET Core DI Framework выглядит правильно.

Сообщите нам, как происходит поиск и устранение неисправностей, и укажите дополнительную информацию о том, какие ошибки вы видите. Удачи!

Ответ 2

Похоже на вопрос DI. Вы вводите ApplicationDbContext context. Это означает, что ApplicationDbContext будет разрешено из контейнера DI, что означает, что он останется открытым весь запрос (переходный), как указал Цзэн. Он должен быть ограничен. Вы можете ввести IServiceScopeFactory scopeFactory в свой контроллер и сделать что-то вроде:

using (var scope = _scopeFactory.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
}

Обратите внимание, что если вы используете ASP.NET Core 1.1 и хотите быть уверенным, что все ваши службы будут правильно решены, измените метод ConfigureService в Startup на:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // Register services
    return services.BuildServiceProvider(validateScopes: true);
}