【Azure 雲服務】在Cloud Service的程式碼中如何修改IIS Application Pool的配置呢? 比如IdleTimeout, startMode, Recycling.PeriodicRestart.Time等

路邊兩盞燈發表於2021-03-26

【Azure 雲服務】在Cloud Service的程式碼中如何修改IIS Application Pool的配置呢? 比如IdleTimeout, startMode, Recycling.PeriodicRestart.Time等

什麼是 PaaS?Platform as a Service 

平臺即服務 (PaaS) 是雲中的完整開發和部署環境,你可以使用其中資源交付內容,從基於雲的簡單應用到啟用雲的複雜企業應用程式皆可。你以即用即付的方式從雲服務提供商處購買所需資源,並通過安全的 Internet 連線訪問這些資源。

 

類似 IaaS,PaaS 也包括伺服器、儲存空間和網路等基礎結構,但它還包括中介軟體、開發工具、商業智慧 (BI) 服務和資料庫管理系統等。PaaS 旨在支援 Web 應用程式的完整生命週期:生成、測試、部署、管理和更新。

 

PaaS 讓你無需購買和管理軟體許可證、底層應用程式基礎結構和中介軟體、容器業務流程協調程式(如 Kubernetes)或開發工具及其他資源,從而避免了開支和複雜操作。你管理自己開發的應用程式和服務,剩餘事項一般由雲服務提供商負責。

 

來源:https://azure.microsoft.com/en-us/overview/what-is-paas/

問題描述

Azure Cloud Service: 是平臺即服務 (PaaS) 的一個示例,是一項基於 HTTP 的服務,用於託管 Web 應用程式、REST API 和移動後端 。它託管在虛擬機器 (VM) 上,通過 IIS 自動部署和託管應用。

所以,當我們想要修改IIS的一些預設的配置時,如何操作呢?

  • IdleTimeout: 預設值為20分鐘,如果在20分鐘Site不活動的情況下(沒有新請求進入),IIS將終止工作程式以釋放資源。
  • Start Mode:工作程式啟動模式, AlwaysRunning(一直執行:如果Application Pool正在執行,請立即啟動w3wp.exe程式。)  OnDemand(按需啟動:如果Application Pool正在執行,則在有第一個入站應用程式請求時啟動w3wp.exe程式)
  • Recycling.PeriodicRestart.Time(Regular Time Interval):預設值為1740分鐘,29小時。當Application Pool每執行29小時後,會自動回收。然後重啟Application Pool。

在部署雲服務(Cloud Service)時,有多種方式實現以上的修改。如新增啟動任務通過CMD命令修改IIS配置(見文末附件部分),或通過程式碼修改,在WebRole的OnStart()方法中實現(本文就介紹程式碼如何實現)。

 

實現程式碼

準備條件:參考官方快速入門,使用VS 2019快速建立Cloud Service專案(Azure 雲服務(經典)和 ASP.NET 入門

【Azure 雲服務】在Cloud Service的程式碼中如何修改IIS Application Pool的配置呢? 比如IdleTimeout, startMode, Recycling.PeriodicRestart.Time等

第一步:在WebRole.cs檔案 OnStart()方法中加入對Servicer Manager的修改程式碼。在使用時候,需要引用Microsoft.Web.Administration.dll。檔案路徑為:C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll

 【Azure 雲服務】在Cloud Service的程式碼中如何修改IIS Application Pool的配置呢? 比如IdleTimeout, startMode, Recycling.PeriodicRestart.Time等

第二步:修改IIS Application Pool

  1. preloadEnabled:設定為ture,當Application Pool啟動時,會自動想站點傳送一個假請求。使得W3WP.EXE程式啟動,當真實的第一個請求進入時馬上進入業務處理,而避免為啟動站點而消耗的時間。它與startMode="AlwaysRunning"配合
  2. startMode:設定為AlwaysRunning
  3. IdleTimeout:設定為0,表示沒有閒置時間,W3WP.EXE程式不會自動終止
  4. PeriodicRestart Time:設定為0,表示Applicaiton Pool不進行回收。
  5. periodicRestart schedule:設定為05:00:00, 表示每天早上5點計劃重啟Application Pool。
        public override bool OnStart()
        {
            ServicePointManager.DefaultConnectionLimit = 12;
            if (!RoleEnvironment.IsEmulated)
            {
                using (ServerManager serverManager = new ServerManager())
                {
                    // 1.參照https://stackoverflow.com/questions/24676194/azure-web-role-warm-up-strategies
                    foreach (var app in serverManager.Sites.SelectMany(x => x.Applications))
                    {
                        app["preloadEnabled"] = true;
                    }
                    foreach (var appPool in serverManager.ApplicationPools)
                    {
                        appPool.AutoStart = true;
                        appPool["startMode"] = "AlwaysRunning";
                        appPool.ProcessModel.IdleTimeout = TimeSpan.Zero;
                        appPool.Recycling.PeriodicRestart.Time = TimeSpan.Zero;

                        //// 2.參照https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/applicationpools/add/recycling/periodicrestart/
                        //// < recycling logEventOnRecycle = "Schedule" >
                        ////  < periodicRestart >
                        ////   < schedule >
                        ////     < add value = "03:00:00" />
                        ////   </ schedule >
                        ////  </ periodicRestart >
                        //// </ recycling >
                        ConfigurationElement periodicRestartElement = appPool.Recycling.GetChildElement("periodicRestart");
                        ConfigurationElementCollection scheduleCollection = periodicRestartElement.GetCollection("schedule");
                        ConfigurationElement addElement1 = scheduleCollection.CreateElement("add");
                        addElement1["value"] = TimeSpan.Parse("05:00:00");
                        scheduleCollection.Add(addElement1);
                    }
                    serverManager.CommitChanges();
                }
            }
            // For information on handling configuration changes
            // see the MSDN topic at https://go.microsoft.com/fwlink/?LinkId=166357.
            return base.OnStart();
        }

 

第三步:提交修改 ( serverManager.CommitChanges();)

 

第四步:在部署的時候,由於修改IIS配置需要提升許可權,所以在釋出時候需要在WebRole的配置檔案(ServiceDefinition.csdef)中設定 <Runtime executionContext="elevated" />

 【Azure 雲服務】在Cloud Service的程式碼中如何修改IIS Application Pool的配置呢? 比如IdleTimeout, startMode, Recycling.PeriodicRestart.Time等 

釋出後RDP到示例中驗證

【Azure 雲服務】在Cloud Service的程式碼中如何修改IIS Application Pool的配置呢? 比如IdleTimeout, startMode, Recycling.PeriodicRestart.Time等

 

附錄一:使用啟動任務方式修改IIS配置

(引用:https://blog.nilayparikh.com/azure/development/using-startup-task-to-manage-application-pool-settings-in-azure-web-role/

Follow the simple steps to gain granular control over Web Role process.

  1. Create Startup.cmd to the project root folder referenced by your web role project.

  2. Change content properties to Copy if newer for Startup.cmd

  3. Add following code to Startup.cmd - as needed.

    Disable idle

      %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00
    

    Auto start

      %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.autoStart:true
    

    Always running

      %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.startMode:AlwaysRunning
    

    Disable recycling

      %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.recycling.periodicRestart.time:00:00:00
    
  4. Save the file as UTF-8 without a signature. (Tip: File Menu > Advanced Save Options in Visual Studio.)

  5. Test the same in Azure Emulator Express - making sure that the code is not breaking anything.

  6. Modify ServiceDefinition.csdef to add the task and elevated attribute.

    <ServiceDefinition name="NilayCornerService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
        <WorkerRole name="NilayCornerWorkerRole1">
            ...
            <Startup>
                <Task commandLine="Startup.cmd" executionContext="elevated" taskType="simple" />
            </Startup>
        </WorkerRole>
    </ServiceDefinition>
    

Tip for advanced usage

To see a list of available options per section, try the following command

%windir%\system32\inetsrv\appcmd set config -section:applicationPools -?

附錄二:部署時遇見的錯誤

Unhandled Exception: Filename: Error: Unrecognized element 'recycling' at Microsoft.Web.Administration.Interop.IAppHostElement.GetElementByName(String bstrSubName) at Microsoft.Web.Administration.ConfigurationElement.GetChildElement(String elementName) at WebRole1.WebRole.OnStart() in C:\Users\bulu\source\repos\AzureCloudService3\WebRole1\WebRole.cs:line 43 at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum) at Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.<InitializeRole>b__0() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() ' [2021-03-25T08:47:15Z] Last exit time: [2021/03/25, 08:47:15.149]. Last exit code: 0.

程式碼中出現重複獲取Recycling節點

ConfigurationElement periodicRestartElement = appPool.Recycling.GetChildElement("recycling").GetChildElement("periodicRestart");

修改為

ConfigurationElement periodicRestartElement = appPool.Recycling.GetChildElement("periodicRestart"); 

修改後,問題消失。

 

參考資料

IIS: Idle Timeout vs Recyclehttps://stackoverflow.com/questions/19985710/iis-idle-timeout-vs-recycle

Azure Web Role “warm up” strategies [closed]https://stackoverflow.com/questions/24676194/azure-web-role-warm-up-strategies

Periodic Restart Settings for Application Pool Recycling <periodicRestart>https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/applicationpools/add/recycling/periodicrestart/

Azure 雲服務(經典)和 ASP.NET 入門https://docs.azure.cn/zh-cn/cloud-services/cloud-services-dotnet-get-started

 

相關文章