How do I prevent SNAT port exhaustion caused by server-side rendering of Angular app on Azure App Service

Josh Berry 1 Reputation point
2020-12-14T15:20:42.29+00:00

I have an app built using the ASP.NET Core Angular spa template (https://learn.microsoft.com/en-us/aspnet/core/client-side/spa/angular) with server-side rendering (SSR) enabled. The app is deployed to an Azure App Service.

Everything works fine until the app receives a large number of requests (~ 1000) in a short period. At that point, the number of outbound connections from the app service increases dramatically and SNAT port exhaustion occurs. After some troubleshooting, it appears that the source of the increase in outbound connections is the node service making calls back to the app itself to perform SSR.

The details of performing SSR are handled inside the ASP.NET Core pre-rendering logic, so I'm not sure how to make it reuse http connections and/or how to configure keepalive on the node service.

Does anyone know how to force the reuse of http connections when performing SSR with ASP.NET Core? Seems like there must be a way to do this or it would be impossible to scale any app that uses SSR.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,231 questions
Azure App Service
Azure App Service
Azure App Service is a service used to create and deploy scalable, mission-critical web apps.
7,003 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Ryan Hill 26,236 Reputation points Microsoft Employee
    2020-12-17T01:52:38.05+00:00

    HI @JoshBerry-1267,

    You can control the number of HttpClient opened by using a singleton via AddHttpClient. To limit the number of connections your HttpClient uses, you can set MaxConnectionsPerServer to value less than 1K. Getting this right can be tricky so it's advised that you start a low number and increase if needed.

    // add to ConfigureServices  
    services.AddHttpClient(Options.DefaultName).ConfigurePrimaryHttpMessageHandler(()=>  
    {  
        return new HttpClientHandler()  
        {  
            MaxConnectionsPerServer = 500  
        };  
    });  
    

    See https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0#configure-the-httpmessagehandler

    EDIT: The above won't apply to Angular as ASP.NET Core will spin up a Node.js process. The following however, https://learn.microsoft.com/en-us/azure/app-service/app-service-web-nodejs-best-practices-and-troubleshoot-guide#my-node-application-is-making-excessive-outbound-calls may help. It suggests using agentKeepAlive options on your http object to control connections being made.

    let keepaliveAgent = new Agent({  
        maxSockets: 32,  
        maxFreeSockets: 10,  
        timeout: 60000,  
        keepAliveTimeout: 300000  
    });  
    

    Regards,
    Ryan