如何配置和运行 Azure 云服务(经典)的启动任务

重要

从 2024 年 9 月 1 日开始,已弃用所有客户的云服务(经典版)。 从 2024 年 10 月开始,Microsoft 将停止并关闭任何正在运行的现有部署,数据将永久性丢失。 新部署应使用基于 Azure 资源管理器的新型部署模型 Azure 云服务(外延支持)

角色启动之前,可以使用启动任务执行操作。 可能需要执行的操作包括安装组件、注册组件对象模型 (COM) 组件、设置注册表项或启动长期运行的进程。

注意

启动任务不适用于虚拟机,只适用于云服务 Web 角色和辅助角色。

启动任务的工作方式

启动任务是在角色开始前执行的操作。 ServiceDefinition.csdef 文件使用 Startup 元素中的 Task 元素定义启动任务。 启动任务通常是批处理文件,但它们也可以是控制台应用程序或启动 PowerShell 脚本的批处理文件。

环境变量将信息传递给启动任务,而本地存储可用于从启动任务中传出信息。 例如,环境变量可以指定要安装的程序的路径,并可以将文件写入到本地存储。 角色可以从此处读取文件。

启动任务可以将信息和错误记录到 TEMP 环境变量指定的目录。 在云中运行时,在启动任务期间,TEMP 环境变量将解析为 C:\Resources\temp\[guid].[rolename]\RoleTemp 目录。

此外,启动任务还可以在重新启动之间执行多次。 例如,每次角色回收时都会运行启动任务,但角色回收可能不会始终包括重新启动。 应以这样的方式编写启动任务:使其能够多次运行而不会出现问题。

启动任务必须以为零的 errorlevel(或退出代码)结束,才能完成启动过程。 如果启动任务以非零 errorlevel 结束,则角色将无法启动。

角色启动顺序

下面列出了 Azure 中的角色启动过程:

  1. 实例将会标记为“正在启动”并且不接收流量。

  2. 所有启动任务均根据其 taskType 属性执行。

    • simple 任务以同步方式执行(一次一个任务)。

    • backgroundforeground 任务与启动任务并行,以异步方式启动。

      警告

      在启动过程中的启动任务阶段,IIS 可能未完全配置,因此角色特定的数据可能不可用。 需要角色特定数据的启动任务应使用 Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint.OnStart

  3. 此时会启动角色主机进程,并在 Internet Information Services (IIS) 中创建站点。

  4. 将调用 Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint.OnStart 方法。

  5. 实例将标记为“就绪”,并且流量将路由到实例。

  6. 将调用 Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint.Run 方法。

启动任务的示例

启动任务在 ServiceDefinition.csdef 文件的 任务 元素中定义。 commandLine 属性可指定启动批处理文件或控制台命令的名称和参数,executionContext 属性指定启动任务的权限级别,taskType 属性则指定该任务的执行方式。

在本示例中,将为启动任务创建环境变量 MyVersionNumber,并将该变量设为值“1.0.0.0”。

ServiceDefinition.csdef

<Startup>
    <Task commandLine="Startup.cmd" executionContext="limited" taskType="simple" >
        <Environment>
            <Variable name="MyVersionNumber" value="1.0.0.0" />
        </Environment>
    </Task>
</Startup>

在下面的示例中,Startup.cmd 批处理文件会将行“The current version is 1.0.0.0”写入到由 TEMP 环境变量指定的目录下的 StartupLog.txt 文件中。 EXIT /B 0 行确保启动任务以为零的 errorlevel 结束。

ECHO The current version is %MyVersionNumber% >> "%TEMP%\StartupLog.txt" 2>&1
EXIT /B 0

注意

在 Visual Studio 中,启动批处理文件的“复制到输出目录”属性应设为“始终复制”,以确保将启动批处理文件正确部署到 Azure 上的项目(对于 Web 角色,为 approot\bin;对于辅助角色,为 approot)。

任务属性的说明

下面介绍 ServiceDefinition.csdef 文件中的任务元素的属性:

commandLine - 为启动任务指定命令行:

  • 该命令具有可选的命令行参数,用于开始启动任务。
  • 此属性通常是 .cmd 或 .bat 批处理文件的文件名。
  • 该任务相对于部署的 AppRoot\Bin 文件夹。 确定任务的路径和文件时,不会扩展环境变量。 如果需要环境扩展,则可以创建用于调用启动任务的小型 .cmd 脚本。
  • 可以是一个启动 PowerShell 脚本的控制台应用程序或批处理文件。

executionContext - 为启动任务指定权限级别。 权限级别可以为 limited 或 elevated:

  • limited
    启动任务以与角色相同的权限运行。 当 Runtime 元素的 executionContext 属性也是 limited 时,则使用用户权限。
  • elevated
    启动任务以管理员特权运行。 借助这些权限,启动任务可以安装程序、更改 IIS 配置、执行注册表更改和其他管理员级别任务,而不会提高角色本身的权限级别。

注意

启动任务的权限级别不需要与角色本身相同。

taskType - 指定启动任务的执行方式。

  • simple
    任务按照 ServiceDefinition.csdef 文件中指定的顺序一次一个地以同步方式执行。 当一个 simple 启动任务以为零的 errorlevel 结束时,将执行下一个 simple 启动任务。 如果不再需要执行其他的简单启动任务,则将启动角色本身。

    注意

    如果 simple 任务以非零 errorlevel 结束,则将阻止该实例。 后续 simple 启动任务和角色本身将不会启动。

    若要确保批处理文件以为零的 errorlevel 结束,请在批处理文件进程结束时执行命令 EXIT /B 0

  • background
    任务与角色同时启动,并以异步方式执行。

  • foreground
    任务与角色同时启动,并以异步方式执行。 前台任务和后台任务之间的关键区别在于前台仼务会在任务结束前阻止角色回收或关闭。 后台任务则没有此限制。

环境变量

环境变量是一种将信息传递给启动任务的方法。 例如,可以放置一个 blob 的路径,该 blob 包含要安装的程序或角色将使用的端口号,或用于控制启动任务的功能的设置。

启动任务有两种类型的环境变量;静态环境变量和基于 RoleEnvironment 类的成员的环境变量。 这两种环境变量都在 ServiceDefinition.csdef 文件的 Environment 节中,并且都使用变量元素和 name 属性。

静态环境变量使用 Variable 元素的 value 属性。 上面的示例创建了环境变量 MyVersionNumber,该变量具有静态值“1.0.0.0”。 另一个示例则是创建 StagingOrProduction 环境变量,可以手动将该变量设置为值“staging”或“production”,以根据 StagingOrProduction 环境变量的值执行不同的启动操作。

基于 RoleEnvironment 类的成员的环境变量不使用 Variable 元素的 value 属性。 而是使用具有相应 XPath 属性值的 RoleInstanceValue 子元素基于 RoleEnvironment 类的特定成员创建环境变量。 用于访问各种 RoleEnvironment 值的 XPath 属性值可以在此处找到。

例如,若要创建这样一个环境变量(当实例在计算模拟器中运行时为“true”,在云中运行时为“false”),请使用以下变量RoleInstanceValue 元素 :

<Startup>
    <Task commandLine="Startup.cmd" executionContext="limited" taskType="simple">
        <Environment>

            <!-- Create the environment variable that informs the startup task whether it is running
                in the Compute Emulator or in the cloud. "%ComputeEmulatorRunning%"=="true" when
                running in the Compute Emulator, "%ComputeEmulatorRunning%"=="false" when running
                in the cloud. -->

            <Variable name="ComputeEmulatorRunning">
                <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
            </Variable>

        </Environment>
    </Task>
</Startup>

后续步骤

了解如何使用云服务执行一些常见的启动任务

打包云服务。