你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将应用从 Azure Functions 版本 1.x 迁移到版本 4.x

重要

Azure Functions 运行时版本 1.x 不支持 Java。 也许你是想要将 Java 应用从版本 3.x 迁移到版本 4.x。 如果要迁移函数应用版本 1.x,请选择上面的 C# 或 JavaScript。

重要

Azure Functions 运行时版本 1.x 不支持 TypeScript。 也许你是想要将 TypeScript 应用从版本 3.x 迁移到版本 4.x。 如果要迁移函数应用版本 1.x,请选择上面的 C# 或 JavaScript。

重要

Azure Functions 运行时版本 1.x 不支持 PowerShell。 也许你是想要将 PowerShell 应用从版本 3.x 迁移到版本 4.x。 如果要迁移函数应用版本 1.x,请选择上面的 C# 或 JavaScript。

重要

Azure Functions 运行时版本 1.x 不支持 Python。 也许你是想要将 Python 应用从版本 3.x 迁移到版本 4.x。 如果要迁移函数应用版本 1.x,请选择上面的 C# 或 JavaScript。

重要

对 Azure Functions 运行时 1.x 版的支持将于 2026 年 9 月 14 日结束。 强烈建议按照本文中的说明将应用迁移到版本 4.x。

本文将指导你完成安全迁移函数应用以在 Functions 运行时版本 4.x 上运行的过程。 由于项目迁移说明与语言相关,因此请务必从文章顶部的选择器中选择你的开发语言。

如果是在 Azure Stack Hub 中运行 1.x 版的运行时,请先参阅 Azure Stack Hub 注意事项

确定要迁移的函数应用

使用以下 PowerShell 脚本,在订阅中生成当前面向版本 1.x 的函数应用的列表:

$Subscription = '<YOUR SUBSCRIPTION ID>' 

Set-AzContext -Subscription $Subscription | Out-Null

$FunctionApps = Get-AzFunctionApp

$AppInfo = @{}

foreach ($App in $FunctionApps)
{
     if ($App.ApplicationSettings["FUNCTIONS_EXTENSION_VERSION"] -like '*1*')
     {
          $AppInfo.Add($App.Name, $App.ApplicationSettings["FUNCTIONS_EXTENSION_VERSION"])
     }
}

$AppInfo

选择目标 .NET 版本

在 Functions 运行时版本 1.x 上,C# 函数应用面向 .NET Framework。

迁移函数应用时,你将有机会选择 .NET 的目标版本。 可以将 C# 项目更新到 Functions 版本 4.x 支持的以下 .NET 版本之一:

.NET 版本 .NET 官方支持策略版本类型 Functions 进程模型1,2
.NET 9 预览版3 独立工作模型
.NET 8 LTS(2026 年 11 月 10 日终止支持) 独立工作模型
进程内模型2
.NET 6 LTS(2024 年 11 月 12 日结束支持) 独立工作模型
进程内模型2
.NET Framework 4.8 查看策略 独立工作模型

1独立工作模型支持 .NET 的长期支持 (LTS) 和标准期限支持 (STS),以及 .NET Framework。 而进程内模型仅支持 .NET 的 LTS 版本,最高到 .NET 8。 有关两类模型之间完整的特性和功能比较,请参阅进程内和独立工作进程 .NET Azure Functions 之间的差异

2 对进程内模型的支持将于 2026 年 11 月 10 日结束。 有关详细信息,请参阅此支持公告。 为了继续获得完全支持,应将应用迁移到独立的辅助角色模型

3 有关支持、当前限制以及预览版使用说明的详细信息,请参阅独立辅助角色模型中的预览 .NET 版本

提示

除非应用依赖于仅适用于 .NET Framework 的库或 API,否则建议你在隔离工作进程模型上更新到 .NET 8。 版本 1.x 上的许多应用仅面向 .NET Framework,因为这是它们创建时可用的内容。 其他功能可用于较新版本的 .NET,如果应用因依赖项而未被迫保持 .NET Framework,你应该以更新的版本为目标。 .NET 8 是完全发布的版本,具有最长的 .NET 支持窗口。

虽然可以选择改用进程内模型,但不建议这样做(如果可以避免)。 对进程内模型的支持将于 2026 年 11 月 10 日结束,因此需要在此之前迁移到隔离的辅助角色模型。 在迁移到版本 4.x 的同时这样做会减少所需的总工作量,而隔离的辅助角色模型会为应用带来其他优势,包括更轻松地面向 .NET 将来版本的能力。 如果要迁移到独立的辅助角色模型,.NET 升级助手还可以为你处理许多必要的代码更改。

本指南未提供适用于 .NET 6 的特定示例。 如果需要面向该版本,可以改编 .NET 8 示例。

准备迁移

如果尚未开始,请使用Azure PowerShell确定需要在当前 Azure 订阅中迁移的应用列表。

在将应用迁移到 Functions 运行时版本 4.x 之前,应执行以下任务:

  1. 查看版本 1.x 之后的行为更改列表。 从版本 1.x 迁移到版本 4.x 也可能会影响绑定。
  2. 完成迁移本地项目中的步骤,将本地项目迁移到版本 4.x。
  3. 迁移项目后,使用Azure Functions Core Tools版本 4.x 在本地全面测试应用。
  4. 将 Azure 中的函数应用更新到新版本。 如果需要最大程度地减少停机时间,请考虑使用过渡槽在新运行时版本上测试和验证 Azure 中迁移的应用。 然后,可以将具有更新的版本设置的应用部署到生产槽。 有关详细信息,请参阅使用槽进行更新
  5. 将迁移的项目发布到更新的函数应用。

使用 Visual Studio 将版本 4.x 项目发布到较低版本的现有函数应用时,系统会提示让 Visual Studio 在部署期间将该函数应用更新到版本 4.x。 此更新使用不使用槽进行更新中定义的相同过程。

迁移本地项目

以下部分介绍为了在 Functions 版本 4.x 中受支持的 .NET 版本之一上运行,而必须对 C# 项目文件进行的更新。 显示的更新是大多数项目的通用更新。 项目代码可能需要本文中未提及的更新,尤其是在使用自定义 NuGet 包时。

将 C# 函数应用从 Functions 运行时版本 1.x 迁移到版本 4.x 需要对项目代码进行更改。 其中许多更改都是因为 C# 语言和 .NET API 的更改。

选择与目标版本的 .NET 和所需进程模型匹配的选项卡(进程内或独立工作进程)。

提示

如果你要使用独立辅助角色模型迁移到 .NET 的 LTS 或 STS 版本,可以使用 .NET 升级助手来自动进行以下部分中提到的许多更改。

项目文件

以下示例是在版本 1.x 上运行的 .csproj 项目文件:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <AzureFunctionsVersion>v1</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.24" />
  </ItemGroup>
  <ItemGroup>
    <Reference Include="Microsoft.CSharp" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

使用以下过程之一将此 XML 文件更新为在 Functions 版本 4.x 中运行:

这些步骤假定使用本地 C# 项目,并且如果应用改用 C# 脚本(.csx 文件),则应 先转换为项目模型,然后再继续操作。

需要在 .csproj XML 项目文件中进行以下更改:

  1. 设置 PropertyGroup 的值。将 TargetFramework 指定为 net8.0

  2. 设置 PropertyGroup 的值。将 AzureFunctionsVersion 指定为 v4

  3. 将以下 OutputType 元素添加到 PropertyGroup

    <OutputType>Exe</OutputType>
    
  4. ItemGroup.PackageReference 列表中,把对 Microsoft.NET.Sdk.Functions 的包引用替换为以下引用:

      <FrameworkReference Include="Microsoft.AspNetCore.App" />
      <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
      <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.2" />
      <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
      <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
      <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
    

    记下对 Microsoft.Azure.WebJobs.* 命名空间中其他包的所有引用。 你将后面的步骤中替换这些包。

  5. 添加以下新的 ItemGroup

    <ItemGroup>
      <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext"/>
    </ItemGroup>
    

进行这些更改后,更新的项目应如以下示例所示:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <RootNamespace>My.Namespace</RootNamespace>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.2" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
    <!-- Other packages may also be in this list -->
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext"/>
  </ItemGroup>
</Project>

包和命名空间更改

根据要迁移到的模型,可能需要更新或更改应用程序引用的包。 采用目标包时,需要更新 using 语句的命名空间以及引用的一些类型。 可以在本文之后的usingHTTP 触发器模板示例中查看这些命名空间更改对语句的影响。

如果尚未更新,请更新项目以引用以下项的最新稳定版本:

根据应用使用的触发器和绑定,你的应用可能需要引用一组不同的包。 下表显示了一些最常用的扩展的替代项:

方案 对包引用的更改
计时器触发器 添加
Microsoft.Azure.Functions.Worker.Extensions.Timer
存储绑定 Replace
Microsoft.Azure.WebJobs.Extensions.Storage
替换为
Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs
Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues
Microsoft.Azure.Functions.Worker.Extensions.Tables
Blob 绑定 把对
Microsoft.Azure.WebJobs.Extensions.Storage.Blobs
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs
队列绑定 把对
Microsoft.Azure.WebJobs.Extensions.Storage.Queues
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues
表绑定 把对
Microsoft.Azure.WebJobs.Extensions.Tables
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.Tables
Cosmos DB 绑定 把对
Microsoft.Azure.WebJobs.Extensions.CosmosDB
和/或
Microsoft.Azure.WebJobs.Extensions.DocumentDB
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.CosmosDB
服务总线绑定 把对
Microsoft.Azure.WebJobs.Extensions.ServiceBus
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.ServiceBus
事件中心绑定 把对
Microsoft.Azure.WebJobs.Extensions.EventHubs
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.EventHubs
事件网格绑定 把对
Microsoft.Azure.WebJobs.Extensions.EventGrid
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.EventGrid
SignalR 服务绑定 把对
Microsoft.Azure.WebJobs.Extensions.SignalRService
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.SignalRService
Durable Functions 把对
Microsoft.Azure.WebJobs.Extensions.DurableTask
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.DurableTask
Durable Functions
(SQL 存储提供程序)
把对
Microsoft.DurableTask.SqlServer.AzureFunctions
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.DurableTask.SqlServer
Durable Functions
(Netherite 存储提供程序)
把对
Microsoft.Azure.DurableTask.Netherite.AzureFunctions
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.DurableTask.Netherite
SendGrid 绑定 把对
Microsoft.Azure.WebJobs.Extensions.SendGrid
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.SendGrid
Kafka 绑定 把对
Microsoft.Azure.WebJobs.Extensions.Kafka
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.Kafka
RabbitMQ 绑定 把对
Microsoft.Azure.WebJobs.Extensions.RabbitMQ
的引用替换为最新版本的
Microsoft.Azure.Functions.Worker.Extensions.RabbitMQ
依赖关系注入
和启动配置
移除了对以下项的引用
Microsoft.Azure.Functions.Extensions
(独立工作器模型默认提供此功能。)

有关要考虑的扩展的完整列表,请参阅受支持的绑定;有关独立进程模型的完整安装说明,请参阅每个扩展的文档。 必须安装任何目标包的最新稳定版本。

提示

在此过程中对扩展版本所做的任何更改可能还要求你更新 host.json 文件。 请务必阅读所使用的每个扩展的文档。 例如,服务总线扩展在版本 4.x 和 5.x 之间的结构中发生了中断性变更。 有关详细信息,请参阅 Azure Functions 的 Azure 服务总线绑定

隔离的工作器模型应用程序不能引用 Microsoft.Azure.WebJobs.* 命名空间中的任何包,也不能引用 Microsoft.Azure.Functions.Extensions 如果有对这些内容的任何剩余引用,应将其删除。

提示

应用还可能依赖于 Azure SDK 类型,无论是作为触发器和绑定的一部分,还是作为独立的依赖项。 还应利用此机会更新这些内容。 最新版本的 Functions 扩展适用于最新版本的Azure SDK for .NET,这些内容几乎所有的包都是Azure.*形式。

仅运行时版本 1.x 支持通知中心移动应用绑定。 升级到运行时版本 4.x 时,需要删除这些绑定,以便直接通过这些服务的 SDK 来使用这些服务。

Program.cs 文件

在大多数情况下,需要将以下 program.cs 文件添加到项目才可进行迁移:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services => {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();

此示例包括 ASP.NET Core 集成以提高性能,并在应用使用 HTTP 触发器时提供熟悉的编程模型。 如果不打算使用 HTTP 触发器,则可以将对 ConfigureFunctionsWebApplication 的调用替换为对 ConfigureFunctionsWorkerDefaults 的调用。 如果这样做,则可以从项目文件中删除对 Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore 的引用。 但是,为了获得最佳性能,即使对于具有其他触发器类型的函数,也应保留对 ASP.NET Core 的 FrameworkReference

Program.cs 文件将替换任何具有 FunctionsStartup 属性的文件(通常是 Startup.cs 文件)。 在 FunctionsStartup 代码将引用 IFunctionsHostBuilder.Services 的位置,可以改为在 Program.csHostBuilder.ConfigureServices() 方法中添加语句。 若要了解有关使用 Program.cs 的详细信息,请参阅独立工作器模型指南中的启动和配置

上面默认的 Program.cs 示例包括独立辅助角色模型的 Application Insights 集成设置。 在你的 Program.cs 中,还必须配置任何应该应用于项目中代码的日志的日志筛选。 在隔离的辅助角色模型中,host.json 文件仅控制 Functions 主机运行时发出的事件。 如果未在 Program.cs 中配置筛选规则,则可能会看到遥测中存在各种类别的日志级别差异。

尽管可以将自定义配置源注册为 HostBuilder 中的一部分,但请注意,这些源同样仅适用于你的项目中的代码。 平台还需要触发器和绑定配置,这应通过应用程序设置Key Vault 引用应用程序配置引用功能提供。

将任何现有 FunctionsStartup 中的所有内容移动到 Program.cs 文件后,便可以删除 FunctionsStartup 属性及其应用到的类。

host.json 文件

host.json 文件中的设置在本地和 Azure 中都在函数应用级别适用。 在版本 1.x 中,host.json 文件为空,或者包含一些适用于函数应用中所有函数的设置。 有关详细信息,请参阅 Host.json v1。 如果 host.json 文件具有设置值,请查看 host.json v2 格式是否有任何更改。

若要在版本 4.x 上运行,必须将 "version": "2.0" 添加到 host.json 文件。 还应考虑将 logging 添加到配置中,如以下示例所示:

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingSettings": {
                "isEnabled": true,
                "excludedTypes": "Request"
            },
            "enableLiveMetricsFilters": true
        }
    }
}

host.json 文件仅控制来自 Functions 主机运行时的日志记录,在隔离的辅助角色模型中,其中一些日志直接来自应用程序,这给了你更多控制。 有关如何筛选这些日志的详细信息,请参阅在独立辅助角色模型中管理日志级别

local.settings.json 文件

只有在本地运行时才使用 local.settings.json 文件。 有关信息,请参阅本地设置文件。 在版本 1.x 中,local.settings.json 文件只有两个必需值:

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "AzureWebJobsStorageConnectionStringValue",
        "AzureWebJobsDashboard": "AzureWebJobsStorageConnectionStringValue"
    }
}

迁移到版本 4.x 时,请确保 local.settings.json 文件至少包含以下元素:

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "AzureWebJobsStorageConnectionStringValue",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
    }
}

注意

从进程内运行迁移到在独立工作进程中运行时,需要将FUNCTIONS_WORKER_RUNTIME值更改为 "dotnet-isolated"。

类名更改

在版本 1.x 和版本 4.x 之间,某些关键类的名称发生了更改。 这些更改是由于 .NET API 发生了更改,或进程内和独立工作进程之间存在差异。 下表列出了 Functions 使用的、迁移时可能会更改的关键 .NET 类:

版本 1.x .NET 8
FunctionName(属性) Function(属性)
TraceWriter ILogger<T>ILogger
HttpRequestMessage HttpRequestData, HttpRequest(使用ASP.NET Core 集成
HttpResponseMessage HttpResponseData, IActionResult(使用ASP.NET Core 集成

绑定中也可能存在类名差异。 有关详细信息,请参阅特定绑定的参考文章。

其他代码更改

本部分重点介绍在迁移过程中要考虑的其他代码更改。 不是所有应用程序都需要这些更改,但你应评估它们是否与你的方案相关。 请务必检查版本 1.x 之后的行为更改,了解可能需要对项目进行的其他更改。

JSON 序列化

默认情况下,独立辅助角色模型将 System.Text.Json 用于 JSON 序列化。 若要自定义序列化程序选项或切换到 JSON.NET (Newtonsoft.Json),请参阅这些说明

Application Insights 日志级别和筛选

日志可以从 Functions 主机运行时和你项目中的代码发送到 Application Insights。 host.json 让你可以为主机日志记录配置规则,但要控制来自你的代码的日志,需要将筛选规则配置为你的 Program.cs 的一部分。 有关如何筛选这些日志的详细信息,请参阅在独立辅助角色模型中管理日志级别

HTTP 触发器模板

可在 HTTP 触发的函数中看到版本 1.x 和版本 4.x 之间的大多数代码更改。 版本 1.x 的 HTTP 触发器模板如以下示例所示:

using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;

namespace Company.Function
{
    public static class HttpTriggerCSharp
    {
        [FunctionName("HttpTriggerCSharp")]
        public static async Task<HttpResponseMessage> 
            Run([HttpTrigger(AuthorizationLevel.AuthLevelValue, "get", "post", 
            Route = null)]HttpRequestMessage req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");

            // parse query parameter
            string name = req.GetQueryNameValuePairs()
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            if (name == null)
            {
                // Get request body
                dynamic data = await req.Content.ReadAsAsync<object>();
                name = data?.name;
            }

            return name == null
                ? req.CreateResponse(HttpStatusCode.BadRequest, 
                    "Please pass a name on the query string or in the request body")
                : req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
        }
    }
}

在版本 4.x 中,HTTP 触发器模板如以下示例所示:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace Company.Function
{
    public class HttpTriggerCSharp
    {
        private readonly ILogger<HttpTriggerCSharp> _logger;

        public HttpTriggerCSharp(ILogger<HttpTriggerCSharp> logger)
        {
            _logger = logger;
        }

        [Function("HttpTriggerCSharp")]
        public IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");

            return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
        }
    }
}

若要将项目更新到 Azure Functions 4.x,请执行以下操作:

  1. Azure Functions Core Tools 的本地安装更新到版本 4.x。

  2. 迁移到版本 4.x 上支持的Node.js 版本之一。

  3. versionextensionBundle 元素添加到 host.json,使其如以下示例所示:

    {
        "version": "2.0",
        "extensionBundle": {
            "id": "Microsoft.Azure.Functions.ExtensionBundle",
            "version": "[3.3.0, 4.0.0)"
        }
    }
    

    extensionBundle 元素是必需的,因为在版本 1.x 之后,绑定将作为外部包进行维护。 有关详细信息,请参阅扩展捆绑包

  4. 更新 local.settings.json 文件,使其至少具有以下元素:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "node"
        }
    }
    

    AzureWebJobsStorage 设置可以是 Azurite 存储模拟器,也可以是实际的 Azure 存储帐户。 有关详细信息,请参阅本地存储模拟器

在 Azure 中更新函数应用

在发布迁移的项目之前,需要将 Azure 中函数应用主机的运行时更新到版本 4.x。 Functions 主机使用的运行时版本由 FUNCTIONS_EXTENSION_VERSION 应用程序设置控制,但在某些情况下,还必须更新其他设置。 代码更改和应用程序设置更改都需要重启函数应用。

最简单的方法是在不使用槽的情况下进行更新,然后重新发布应用项目。 也可以在使用槽的情况下进行更新,以最大程度地减少应用中的停机时间并简化回滚。

在不使用槽的情况下进行更新

更新到 v4.x 的最简单方法是在 Azure 中将函数应用上的 FUNCTIONS_EXTENSION_VERSION 应用程序设置设为 ~4。 必须在带有槽的站点上执行其他过程

az functionapp config appsettings set --settings FUNCTIONS_EXTENSION_VERSION=~4 -g <RESOURCE_GROUP_NAME> -n <APP_NAME>

还必须指定另一项设置,用于区分 Windows 和 Linux。

在 Windows 上运行时,还需要启用运行时版本 4.x 所需的 .NET 6.0。

az functionapp config set --net-framework-version v6.0 -g <RESOURCE_GROUP_NAME> -n <APP_NAME>

Windows 上运行的任何语言的函数应用都需要 .NET 6。

在本例中,请将 <APP_NAME> 替换为函数应用的名称,并将 <RESOURCE_GROUP_NAME> 替换为资源组的名称。

现可重新发布已迁移为在版本 4.x 上运行的应用项目。

在使用槽的情况下进行更新

使用部署槽是将函数应用从旧版本更新到 v4.x 运行时的好办法。 通过使用过渡槽,可以在过渡槽中的新运行时版本上运行应用,并在验证后切换到生产槽。 这些槽还提供一种在更新期间最大程度地缩短停机时间的方法。 如果需要最大程度地缩短停机时间,请按照最短停机时间更新中的步骤操作。

在更新槽中验证应用后,可以将应用和新版本设置切换到生产槽。 此切换需要在生产槽中包含设置 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0。 添加此设置的方式会影响更新所需的停机时间。

标准更新

如果启用了槽的函数应用可以处理一次完整重启的停机时间,那么你可以直接在生产槽中更新 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS 设置。 由于直接在生产槽中更改此设置会导致重启,从而影响可用性,因此请考虑在流量减少时执行此更改。 然后,可以从过渡槽中切换更新的版本。

Update-AzFunctionAppSetting PowerShell cmdlet 当前不支持这些槽。 你必须使用 Azure CLI 或 Azure 门户。

  1. 使用以下命令在生产槽中设置 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0

    az functionapp config appsettings set --settings WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0  -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> 
    

    在本例中,请将 <APP_NAME> 替换为函数应用的名称,并将 <RESOURCE_GROUP_NAME> 替换为资源组的名称。 此命令会导致在生产槽中运行的应用重启。

  2. 同样,使用以下命令在过渡槽中设置 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS

    az functionapp config appsettings set --settings WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0 -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME>
    
  3. 使用以下命令更改 FUNCTIONS_EXTENSION_VERSION 并将过渡槽更新到新的运行时版本:

    az functionapp config appsettings set --settings FUNCTIONS_EXTENSION_VERSION=~4 -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME>
    
  4. 在 Windows 中,Functions 运行时版本 4.x 需要 .NET 6。 在 Linux 上,.NET 应用还必须更新到 .NET 6。 使用以下命令使运行时可在 .NET 6 上运行:

    在 Windows 上运行时,还需要启用运行时版本 4.x 所需的 .NET 6.0。

    az functionapp config set --net-framework-version v6.0 -g <RESOURCE_GROUP_NAME> -n <APP_NAME>
    

    Windows 上运行的任何语言的函数应用都需要 .NET 6。

    在本例中,请将 <APP_NAME> 替换为函数应用的名称,并将 <RESOURCE_GROUP_NAME> 替换为资源组的名称。

  5. 如果代码项目需要任何更新才能在版本 4.x 上运行,请立即将这些更新部署到过渡槽。

  6. 在切换之前,请确认函数应用在更新的过渡环境中正常运行。

  7. 使用以下命令将更新的过渡槽切换到生产槽:

    az functionapp deployment slot swap -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME> --target-slot production
    

最短停机时间更新

若要最大程度地缩短生产应用的停机时间,可以将 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS 设置从过渡槽切换到生产槽。 然后,可以从预热过渡槽切换到更新的版本。

  1. 使用以下命令在过渡槽中设置 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0

    az functionapp config appsettings set --settings WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0 -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME>
    
  2. 使用以下命令将带有新设置的槽切换到生产槽,同时还原过渡槽中的版本设置。

    az functionapp deployment slot swap -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME> --target-slot production
    az functionapp config appsettings set --settings FUNCTIONS_EXTENSION_VERSION=~3 -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME>
    

    在切换期间过渡槽可能会出现错误,并且会在暂存时还原运行时版本。 此错误的可能原因是,在交换期间过渡槽中仅包含 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0,因此删除了过渡槽中的 FUNCTIONS_EXTENSION_VERSION 设置。 在没有此版本设置的情况下,槽处于错误状态。 在切换后立即更新过渡槽中的版本应该会将槽重新置于良好状态,并且你可以根据需要调用回滚更改。 但是,对于切换的任何回滚,你还需要在切换返回之前直接从生产槽中删除 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0,以免生产槽中出现与过渡槽中相同的错误。 然后,生产设置中的此更改会导致重启。

  3. 使用以下命令在过渡槽中再次设置 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0

    az functionapp config appsettings set --settings WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0 -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME>
    

    此时,这两个槽都已设置 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS=0

  4. 使用以下命令更改 FUNCTIONS_EXTENSION_VERSION 并将过渡槽更新到新的运行时版本:

    az functionapp config appsettings set --settings FUNCTIONS_EXTENSION_VERSION=~4 -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME>
    
  5. 在 Windows 中,Functions 运行时版本 4.x 需要 .NET 6。 在 Linux 上,.NET 应用还必须更新到 .NET 6。 使用以下命令使运行时可在 .NET 6 上运行:

    在 Windows 上运行时,还需要启用运行时版本 4.x 所需的 .NET 6.0。

    az functionapp config set --net-framework-version v6.0 -g <RESOURCE_GROUP_NAME> -n <APP_NAME>
    

    Windows 上运行的任何语言的函数应用都需要 .NET 6。

    在本例中,请将 <APP_NAME> 替换为函数应用的名称,并将 <RESOURCE_GROUP_NAME> 替换为资源组的名称。

  6. 如果代码项目需要任何更新才能在版本 4.x 上运行,请立即将这些更新部署到过渡槽。

  7. 在切换之前,请确认函数应用在更新的过渡环境中正常运行。

  8. 使用以下命令将更新的预热过渡槽切换到生产槽:

    az functionapp deployment slot swap -g <RESOURCE_GROUP_NAME>  -n <APP_NAME> --slot <SLOT_NAME> --target-slot production
    

版本 1.x 之后的行为更改

本部分详细介绍了在版本 1.x 之后,对触发器和绑定行为以及核心 Functions 功能和行为所做的更改。

触发器和绑定的更改

从版本 2.x 开始,必须为应用中的函数所用的特定触发器和绑定安装扩展。 唯一的例外是 HTTP 和计时器触发器,它们不需要扩展。 有关详细信息,请参阅注册和安装绑定扩展

此外,在不同的版本中,函数的 function.json 或属性存在几处更改。 例如,事件中心的 path 属性现在为 eventHubName。 请参阅现有绑定表,以获取每个绑定的文档链接。

特性和功能的更改

在版本 1.x 后删除、更新或替换了几个特性。 本部分详细介绍了在使用版本 1.x 后,更高版本中会出现的更改。

在版本 2.x 中做出了以下更改:

  • 用于调用 HTTP 终结点的密钥始终以加密方式存储在 Azure Blob 存储中。 在版本 1.x 中,密钥将默认存储在 Azure 文件存储中。 将应用从版本 1.x 迁移到版本 2.x 时,将重置 Azure 文件存储中的现有机密。

  • 2\.x 版运行时不包含对 Webhook 提供程序的内置支持。 做出此项更改的目的是提高性能。 仍可以使用 HTTP 触发器作为 Webhook 的终结点。

  • 为了改进监视功能,门户中使用 AzureWebJobsDashboard 设置的 WebJobs 仪表板已替换为使用 APPINSIGHTS_INSTRUMENTATIONKEY 设置的 Azure Application Insights。 有关详细信息,请参阅监视 Azure Functions

  • 函数应用中的所有函数必须共享相同的语言。 创建函数应用时,必须选择该应用的运行时堆栈。 运行时堆栈由应用程序设置中的 FUNCTIONS_WORKER_RUNTIME 值指定。 增加此项要求的目的是减少占用空间和启动时间。 进行本地开发时,还必须在 local.settings.json 文件中包含此设置。

  • 应用服务计划中函数的默认超时已更改为 30 分钟。 可以使用 host.json 中的 functionTimeout 设置,将超时手动改回到无限。

  • 默认情况下,将对消耗计划函数实施 HTTP 并发性限制,每个实例的并发请求数默认为 100。 可以在 host.json 文件中的 maxConcurrentRequests 设置内更改此行为。

  • 由于 .NET Core 的限制,已删除对 F# 脚本(.fsx 文件)函数的支持。 编译的 F# 函数 (.fs) 仍受支持。

  • 事件网格触发器 Webhook 的 URL 格式已改为遵循此模式:https://{app}/runtime/webhooks/{triggerName}

  • 1.x 版之后,一些预定义的自定义指标的名称发生了更改。 Duration 被替换为 MaxDurationMsMinDurationMsAvgDurationMsSuccess Rate 也已重命名为 Success Rate

Azure Stack Hub 注意事项

Azure Stack Hub 上的应用服务不支持 4.x 版的 Azure Functions。 计划从 Azure Stack Hub 中的版本 1.x 迁移时,可以选择以下选项之一:

  • 按照本文中的说明迁移到公有云中托管的版本 4.x Azure Functions。 无需升级现有应用,而是使用版本 4.x 创建新应用,然后将修改的项目部署到其中。
  • 切换到 Azure Stack Hub 中的应用服务计划上托管的 WebJobs

后续步骤