Azure / azure-libraries-for-net

Azure libraries for .Net
MIT License
380 stars 192 forks source link

Fail to parallel create webapp #596

Open ccic opened 5 years ago

ccic commented 5 years ago

I want to create 30 webapps in parallel through C# SDK. Unfortunately, it always failed. I checked the log on Azure portal, and found there are many "Updating hosting plan" errors and "Updating web site" errors. I used Microsoft.Azure.Management.Fluent 1.18.0 and Microsoft.Azure.Management.Websites 2.0.1

Updating hosting plan error: Operation name Update hosting plan Time stamp Tue Feb 19 2019 21:56:37 GMT+0800 (China Standard Time) Event initiated by 7711bec6-fcf0-4bc6-b549-69df432af894 Error code 429 Message Cannot acquire exclusive lock to create or update this server farm. Retry the request later.

Updating web site error: Operation name Update website Time stamp Tue Feb 19 2019 21:56:36 GMT+0800 (China Standard Time) Event initiated by 7711bec6-fcf0-4bc6-b549-69df432af894 Error code ClientClosedRequest Message The connection has been closed by the client while the server is still processing its request for 'Microsoft.Web'.

The code logic looks like:

        IResourceGroup resourceGroup = GetResourceGroup();
        // assign names
        var rootTimestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
        var webappNameList = new List<string>();
        for (var i = 0; i < _argsOption.WebappCount; i++)
        {
            var name = _argsOption.WebAppNamePrefix + $"{rootTimestamp}{i}";
            webappNameList.Add(name);
        }
        if (!FindPricingTier(_argsOption.PriceTier, out PricingTier targetPricingTier))
        {
            Console.WriteLine($"Unsupported pricing tier: {_argsOption.PriceTier}");
            return;
        }
        // create app service plans. The default ConcurrentCountOfServicePlan is 5, and it is always successful in my test.
        var packages = (from i in Enumerable.Range(0, _argsOption.WebappCount)
                        select (azure : _azure,
                                name : webappNameList[i],
                                region : _argsOption.Location,
                                groupName : _argsOption.GroupName,
                                pricingTier: targetPricingTier,
                                os : Microsoft.Azure.Management.AppService.Fluent.OperatingSystem.Windows)).ToList();

        await BatchProcess(packages, CreateAppPlan, _argsOption.ConcurrentCountOfServicePlan);

        // always fail to create web apps. WebappCount is 30
        var tasks = new List<Task>();
        for (var i = 0; i < _argsOption.WebappCount; i++)
        {
            var name = webappNameList[i];
            var appService = _azure.AppServices.AppServicePlans.GetByResourceGroup(
                _argsOption.GroupName, webappNameList[i]);
            var t = _azure.WebApps.Define(name)
                     .WithExistingWindowsPlan(appService)
                     .WithExistingResourceGroup(resourceGroup)
                     .WithWebAppAlwaysOn(true)
                     .DefineSourceControl()
                     .WithPublicGitRepository(_argsOption.GitHubRepo)
                     .WithBranch("master")
                     .Attach()
                     .WithConnectionString("Azure:SignalR:ConnectionString", _argsOption.ConnectionString,
                     Microsoft.Azure.Management.AppService.Fluent.Models.ConnectionStringType.Custom)
                     .CreateAsync();
            tasks.Add(t);
        }
        await Task.WhenAll(tasks);
ccic commented 5 years ago

My simple question is how to reduce the total app services creation time if I want to create many app services?

praries880 commented 5 years ago

@jianghaolu can you kindly look into this?

ccic commented 5 years ago

This issue is related to https://github.com/Azure/azure-libraries-for-net/issues/609.

I want to create many web apps (>20) in a short period to run SignalR perf test. Firstly, I created many app service plan and web apps, every web app is binding with one of app service plan. I need more than 20 web app instances. The above code snippet is for this purpose.

Later, I recognized it is not necessary to create so many app service plans. Instead, I should use "scale out" of app service plans. For 20 web app instances of S3 size, only 2 app service plans are enough because the maximum capacity is 10.

Then, I encountered the issue 609. The creation of app service plan of S3 with maximum capacity 10 often failed, and it complains "Not enough available reserved instance servers to satisfy this request."

Is there a best practice to avoid such insufficient resource issue?