【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 入门

**第一步:**在WebRole.cs文件 OnStart()方法中加入对Servicer Manager的修改代码。在使用时候,需要引用Microsoft.Web.Administration.dll。文件路径为:C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll

 

**第二步:**修改IIS Application Pool

  • preloadEnabled:设置为ture,当Application Pool启动时,会自动想站点发送一个假请求。使得W3WP.EXE进程启动,当真实的第一个请求进入时马上进入业务处理,而避免为启动站点而消耗的时间。它与startMode="AlwaysRunning"配合

  • startMode:设置为AlwaysRunning

  • IdleTimeout:设置为0,表示没有闲置时间,W3WP.EXE进程不会自动终止

  • PeriodicRestart Time:设置为0,表示Applicaiton Pool不进行回收。

  • 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" />

  

发布后RDP到示例中验证

 

附录一:使用启动任务方式修改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.

-

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

-

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

-

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

Disable idle

<code class=" language-powershell">  %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00
</code>

Auto start

<code class="language-powershell">  %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.autoStart:true
</code>

Always running

<code class="language-powershell">  %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.startMode:AlwaysRunning
</code>

Disable recycling

<code class="language-powershell">  %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.recycling.periodicRestart.time:00:00:00
</code>

Save the file as UTF-8 without a signature. (Tip: File Menu > Advanced Save Options in Visual Studio.)

-

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

-

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

<code class="language-xml">&lt;ServiceDefinition name="NilayCornerService" xmlns="[http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition](http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition)"&gt;
&lt;WorkerRole name="NilayCornerWorkerRole1"&gt;
...
&lt;Startup&gt;
**&lt;Task commandLine="Startup.cmd" executionContext="elevated" taskType="simple" /&gt;**
&lt;/Startup&gt;
&lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</code>

Tip for advanced usage

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

<code class="language-powershell">%windir%\system32\inetsrv\appcmd set config -section:applicationPools -?</code>

附录二:部署时遇见的错误

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

 

正在加载评论...