Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Socket Leaks?

I have an ASP.NET Core a website with a lot of simultaneous users which crashes many times during the day and I scaled up and out but no luck. I have been told my numerous Azure support staff that the issue is that I'm sending out a lot of database calls although database utilization improved after creating indexes. Can you kindly advise what you think the problem is as I have done my best... I was told that I have "socket leaks".

Please note:

  • I don't have any external service calls except to sendgrid
  • I have not used ConfigureAwait(false)

  • I'm not using "using" statements or explicitly disposing contexts

This is my connection string If it may help...

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;

These are some code examples:

In Startup.CS:

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

Main class:

    private readonly ApplicationDbContext _context;

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

This an important method code for example:

       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);

Please advise as I have tried my best but this is very embarrassing to me in font of my customers.

like image 987
Techy Avatar asked Feb 08 '17 04:02

Techy


2 Answers

Without the error messages that you're seeing, here's a few ideas that you can check.

  • I'd start with going to your Web App's Overview blade in the Azure Portal. Update the monitoring graph to a time period when you're experiencing problems. Are you CPU bound? Have you exhausted memory? Also, check the HTTP Queue length. If your HTTP queue is really long, it's because your server is choking trying to service the requests and users are experiencing timeout issues.

    • Next, jump over to your SQL Server's Overview blade in the Azure Portal, and look at the resource utilization chart. Set the time period on the chart to when you're experiencing problems. Have you pegged out your DTUs for your database? If so, it's a sign of poor indexing, poor schema design, or you're just undersized and need to scale up.

    • Turn on ApplicationInsights if you haven't already. You can use the ApplicationInsights API to insert your own trace statements into your code. Or, you might be able to see exceptions causing the issue without having to do your own tracing.

    • Check the Kudu logs for your Web Apps.

I agree with Tseng - your usage of EF and .NET Core's DI framework looks correct.

Let us know how the troubleshooting goes and provide additional information on exactly what kind of errors you're seeing. Best of luck!

like image 87
Rob Reagan Avatar answered Nov 17 '22 19:11

Rob Reagan


It looks like a DI issue to me. You are injecting ApplicationDbContext context. Which means the ApplicationDbContext will be resolved from the DI container meaning it will stay open the entire request (transient) as Tseng pointed out. It should be a scoped. You can inject IServiceScopeFactory scopeFactory in your controller and do something like:

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

Note that if you are using ASP.NET Core 1.1 and want to be sure that all your services are being resolved correctly change your ConfigureService method in the Startup to:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // Register services
    return services.BuildServiceProvider(validateScopes: true);
}
like image 33
user1336 Avatar answered Nov 17 '22 19:11

user1336