using Microsoft.Extensions.Hosting;
using Microsoft.Azure.Functions.Worker;
namespace Company.FunctionApp
internal class Program
static void Main(string[] args)
FunctionsDebugger.Enable();
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services => {
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
.Build();
host.Run();
Program.cs 文件将替换任何具有 FunctionsStartup 属性的文件(通常是 Startup.cs 文件)。 在 FunctionsStartup 代码将引用 IFunctionsHostBuilder.Services 的位置,可以改为在 .ConfigureServices() 中 HostBuilder 的 Program.cs 方法中添加语句。 若要了解有关使用 Program.cs 的详细信息,请参阅独立工作器模型指南中的启动和配置。
上面默认的 Program.cs 示例包括独立辅助角色模型的 Application Insights 集成设置。 在你的 Program.cs 中,还必须配置任何应该应用于项目中代码的日志的日志筛选。 在隔离的辅助角色模型中,host.json 文件仅控制 Functions 主机运行时发出的事件。 如果未在 Program.cs 中配置筛选规则,则可能会看到遥测中存在各种类别的日志级别差异。
尽管可以将自定义配置源注册为 HostBuilder 中的一部分,但请注意,这些源同样仅适用于你的项目中的代码。 平台还需要触发器和绑定配置,这应通过应用程序设置、Key Vault 引用或应用程序配置引用功能提供。
将任何现有 FunctionsStartup 中的所有内容移动到 Program.cs 文件后,便可以删除 FunctionsStartup 属性及其应用到的类。
使用进程内模型时不需要Program.cs文件。
local.settings.json 文件
只有在本地运行时才使用 local.settings.json 文件。 有关信息,请参阅本地设置文件。
迁移到版本 4.x 时,请确保 local.settings.json 文件至少包含以下元素:
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "AzureWebJobsStorageConnectionStringValue",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
从进程内运行迁移到在独立工作进程中运行时,需要将FUNCTIONS_WORKER_RUNTIME值更改为 "dotnet-isolated"。
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "AzureWebJobsStorageConnectionStringValue",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
从进程内运行迁移到在独立工作进程中运行时,需要将FUNCTIONS_WORKER_RUNTIME值更改为 "dotnet-isolated"。
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "AzureWebJobsStorageConnectionStringValue",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"FUNCTIONS_INPROC_NET8_ENABLED": "1"
选择使用进程内模型以 .NET 8 为目标时,需要将 FUNCTIONS_WORKER_RUNTIME 值设置为“dotnet”并将 FUNCTIONS_INPROC_NET8_ENABLED 值设置为“1”。
host.json 文件
无需对 host.json 文件进行更改。 但是,如果此文件中的 Application Insights 配置来自进程内模型项目,则可能需要在 Program.cs 文件中进行其他更改。
host.json 文件仅控制来自 Functions 主机运行时的日志记录,在隔离的辅助角色模型中,其中一些日志直接来自应用程序,这给了你更多控制。 有关如何筛选这些日志的详细信息,请参阅在独立辅助角色模型中管理日志级别。
无需对 host.json 文件进行更改。 但是,如果此文件中的 Application Insights 配置来自进程内模型项目,则可能需要在 Program.cs 文件中进行其他更改。
host.json 文件仅控制来自 Functions 主机运行时的日志记录,在隔离的辅助角色模型中,其中一些日志直接来自应用程序,这给了你更多控制。 有关如何筛选这些日志的详细信息,请参阅在独立辅助角色模型中管理日志级别。
无需对 host.json 文件进行更改。
在版本之间,一些关键类的名称发生了更改。 这些更改是由于 .NET API 发生了更改,或进程内和独立工作进程之间存在差异。 下表列出了 Functions 使用的、迁移时可能会更改的关键 .NET 类:
本部分重点介绍在迁移过程中要考虑的其他代码更改。 所有应用程序都不需要这些更改,但你应该评估是否与方案相关。 请务必检查 3.x 和 4.x 之间的重大变更,以了解可能需要对项目进行的其他更改。
JSON 序列化
默认情况下,独立辅助角色模型将 System.Text.Json 用于 JSON 序列化。 若要自定义序列化程序选项或切换到 JSON.NET (Newtonsoft.Json),请参阅这些说明。
Application Insights 日志级别和筛选
日志可以从 Functions 主机运行时和你项目中的代码发送到 Application Insights。
host.json 让你可以为主机日志记录配置规则,但要控制来自你的代码的日志,需要将筛选规则配置为你的 Program.cs 的一部分。 有关如何筛选这些日志的详细信息,请参阅在独立辅助角色模型中管理日志级别。
本部分重点介绍在迁移过程中要考虑的其他代码更改。 所有应用程序都不需要这些更改,但你应该评估是否与方案相关。 请务必检查 3.x 和 4.x 之间的重大变更,以了解可能需要对项目进行的其他更改。
JSON 序列化
默认情况下,独立辅助角色模型将 System.Text.Json 用于 JSON 序列化。 若要自定义序列化程序选项或切换到 JSON.NET (Newtonsoft.Json),请参阅这些说明。
Application Insights 日志级别和筛选
日志可以从 Functions 主机运行时和你项目中的代码发送到 Application Insights。
host.json 让你可以为主机日志记录配置规则,但要控制来自你的代码的日志,需要将筛选规则配置为你的 Program.cs 的一部分。 有关如何筛选这些日志的详细信息,请参阅在独立辅助角色模型中管理日志级别。
请务必检查 3.x 和 4.x 之间的重大变更,以了解可能需要对项目进行的其他更改。
HTTP 触发器模板
在 HTTP 触发的函数中可以看到进程内和隔离工作进程之间的差异。 版本 3.x(进程内)的 HTTP 触发器模板如以下示例所示:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Company.Function
public static class HttpTriggerCSharp
[FunctionName("HttpTriggerCSharp")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.AuthLevelValue, "get", "post", Route = null)] HttpRequest req,
ILogger log)
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
迁移后的版本的 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"]}!");
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using System.Net;
namespace Company.Function
public class HttpTriggerCSharp
private readonly ILogger<HttpTriggerCSharp> _logger;
public HttpTriggerCSharp(ILogger<HttpTriggerCSharp> logger)
_logger = logger;
[Function("HttpTriggerCSharp")]
public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req)
_logger.LogInformation("C# HTTP trigger function processed a request.");
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString($"Welcome to Azure Functions, {req.Query["name"]}!");
return response;
如果需要,请迁移到版本 4.x 支持的 Java 版本之一。
更新应用的 POM.xml 文件以将 FUNCTIONS_EXTENSION_VERSION 设置修改为 ~4,如以下示例所示:
<configuration>
<resourceGroup>${functionResourceGroup}</resourceGroup>
<appName>${functionAppName}</appName>
<region>${functionAppRegion}</region>
<appSettings>
<property>
<name>WEBSITE_RUN_FROM_PACKAGE</name>
<value>1</value>
</property>
<property>
<name>FUNCTIONS_EXTENSION_VERSION</name>
<value>~4</value>
</property>
</appSettings>
</configuration>
在“Function App 诊断”中,开始键入 ,然后从列表中选择它。
验证完成后,请查看建议并解决应用中的任何问题。 如果需要对应用进行更改,请确保在本地使用 Azure Functions Core Tools v4 或通过使用过渡槽来验证针对 Functions 运行时版本 4.x 的更改。
在 Azure 中升级函数应用
在发布迁移的项目之前,需要将 Azure 中函数应用主机的运行时升级到版本 4.x。 Functions 主机使用的运行时版本由 FUNCTIONS_EXTENSION_VERSION 应用程序设置控制,但在某些情况下,还必须更新其他设置。 代码更改和应用程序设置更改都需要重启函数应用。
最简单的方法是不使用槽进行升级,然后重新发布应用项目。 也可以使用槽进行升级,以最大程度地减少应用中的停机时间并简化回滚。
不使用槽进行升级
升级到 v4.x 的最简单方法是在 Azure 中将函数应用上的 FUNCTIONS_EXTENSION_VERSION 应用程序设置设为 ~4。 必须在带有槽的站点上执行其他过程。
在 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。
在 Windows 上运行时,还需要启用运行时版本 4.x 所需的 .NET 6.0。
Set-AzWebApp -NetFrameworkVersion v6.0 -Name <APP_NAME> -ResourceGroupName <RESOURCE_GROUP_NAME>
Windows 上运行的任何语言的函数应用都需要 .NET 6。
你还可能需要更新 linuxFxVersion 站点设置以面向特定语言版本。 如果已设置正确的 linuxFxVersion 值,则可以跳过此步骤。 有关详细信息,请参阅有效的 linuxFxVersion 值。
在 Functions 4.x 发布之前,Linux 上不支持 PowerShell 应用。 这一事实意味着无需升级 Linux 上运行的 PowerShell 函数应用。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "DOTNET|6.0"
如果你要迁移到 .NET Functions 独立工作进程,请对 DOTNET-ISOLATED|6.0 使用 DOTNET-ISOLATED|7.0 或 --linux-fx-version。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Java|11"
--linux-fx-version 值必须与目标 Java 版本匹配。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Node|16"
--linux-fx-version 值必须与目标 Node.js 版本匹配。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Python|3.9"
--linux-fx-version 值必须与目标 PowerShell 版本匹配。
在本例中,请将 <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 门户。
使用以下命令在生产槽中设置 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> 替换为资源组的名称。 此命令会导致在生产槽中运行的应用重启。
同样,使用以下命令在过渡槽中设置 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>
使用以下命令更改 FUNCTIONS_EXTENSION_VERSION 并将过渡槽升级到新的运行时版本:
az functionapp config appsettings set --settings FUNCTIONS_EXTENSION_VERSION=~4 -g <RESOURCE_GROUP_NAME> -n <APP_NAME> --slot <SLOT_NAME>
在 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。
你还可能需要更新 linuxFxVersion 站点设置以面向特定语言版本。 如果已设置正确的 linuxFxVersion 值,则可以跳过此步骤。 有关详细信息,请参阅有效的 linuxFxVersion 值。
在 Functions 4.x 发布之前,Linux 上不支持 PowerShell 应用。 这一事实意味着无需升级 Linux 上运行的 PowerShell 函数应用。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "DOTNET|6.0"
如果你要迁移到 .NET Functions 独立工作进程,请对 DOTNET-ISOLATED|6.0 使用 DOTNET-ISOLATED|7.0 或 --linux-fx-version。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Java|11"
--linux-fx-version 值必须与目标 Java 版本匹配。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Node|16"
--linux-fx-version 值必须与目标 Node.js 版本匹配。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Python|3.9"
--linux-fx-version 值必须与目标 PowerShell 版本匹配。
在本例中,请将 <APP_NAME> 替换为函数应用的名称,并将 <RESOURCE_GROUP_NAME> 替换为资源组的名称。
如果代码项目需要任何更新才能在版本 4.x 上运行,请立即将这些更新部署到过渡槽。
在切换之前,请确认函数应用在升级的过渡环境中正常运行。
使用以下命令将升级的过渡槽切换到生产槽:
az functionapp deployment slot swap -g <RESOURCE_GROUP_NAME> -n <APP_NAME> --slot <SLOT_NAME> --target-slot production
最短停机时间升级
若要最大程度地缩短生产应用的停机时间,可以将 WEBSITE_OVERRIDE_STICKY_EXTENSION_VERSIONS 设置从过渡槽切换到生产槽。 然后,可以从预热过渡槽切换到升级的版本。
使用以下命令在过渡槽中设置 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>
使用以下命令将带有新设置的槽切换到生产槽,同时还原过渡槽中的版本设置。
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,以免生产槽中出现与过渡槽中相同的错误。 然后,生产设置中的此更改会导致重启。
使用以下命令在过渡槽中再次设置 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。
使用以下命令更改 FUNCTIONS_EXTENSION_VERSION 并将过渡槽升级到新的运行时版本:
az functionapp config appsettings set --settings FUNCTIONS_EXTENSION_VERSION=~4 -g <RESOURCE_GROUP_NAME> -n <APP_NAME> --slot <SLOT_NAME>
在 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。
你还可能需要更新 linuxFxVersion 站点设置以面向特定语言版本。 如果已设置正确的 linuxFxVersion 值,则可以跳过此步骤。 有关详细信息,请参阅有效的 linuxFxVersion 值。
在 Functions 4.x 发布之前,Linux 上不支持 PowerShell 应用。 这一事实意味着无需升级 Linux 上运行的 PowerShell 函数应用。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "DOTNET|6.0"
如果你要迁移到 .NET Functions 独立工作进程,请对 DOTNET-ISOLATED|6.0 使用 DOTNET-ISOLATED|7.0 或 --linux-fx-version。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Java|11"
--linux-fx-version 值必须与目标 Java 版本匹配。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Node|16"
--linux-fx-version 值必须与目标 Node.js 版本匹配。
az functionapp config set --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> --linux-fx-version "Python|3.9"
--linux-fx-version 值必须与目标 PowerShell 版本匹配。
在本例中,请将 <APP_NAME> 替换为函数应用的名称,并将 <RESOURCE_GROUP_NAME> 替换为资源组的名称。
如果代码项目需要任何更新才能在版本 4.x 上运行,请立即将这些更新部署到过渡槽。
在切换之前,请确认函数应用在升级的过渡环境中正常运行。
使用以下命令将升级的预热过渡槽切换到生产槽:
az functionapp deployment slot swap -g <RESOURCE_GROUP_NAME> -n <APP_NAME> --slot <SLOT_NAME> --target-slot production
3\.x 和 4.x 之间的中断性变更
以下是在将 3.x 应用升级到 4.x 之前需要注意的关键中断性变更,其中包括特定于语言的中断性变更。 如需完整列表,请参阅标有中断性变更:已批准的 Azure Functions GitHub 问题。
如果没有看到你的编程语言,请从页面顶部选择。
Azure Functions 代理是 Azure Functions 运行时版本 1.x 到 3.x 的旧功能。 可以在版本 4.x 中重新启用对 Functions 代理的支持,以便你可以成功将函数应用更新为最新运行时版本。 应尽快切换到将函数应用与 Azure API 管理集成。 API 管理使你能够利用一组更完整的功能来定义、保护、管理基于 Functions 的 API 并从中获利。 有关详细信息,请参阅 API 管理集成。 若要了解如何在 Functions 版本 4.x 中重新启用代理支持,请参阅在 Functions v4.x 中重新启用代理。
4\.x 不再支持使用 AzureWebJobsDashboard 登录到 Azure 存储。 应改用 Application Insights。 (#1923)
Azure Functions 4.x 现在强制实施对扩展的最低版本要求。 更新到受影响扩展的最新版本。 对于非 .NET 语言,请更新到扩展包版本 2.x 或更高版本。 (#1987)
现在,对于消耗计划中运行于 Linux 上的函数应用,会强制实施 4.x 中的默认超时和最大超时。 (#1915)
Azure Functions 4.x 为 Key Vault 提供程序使用 Azure.Identity 和 Azure.Security.KeyVault.Secrets,已经弃用了 Microsoft.Azure.KeyVault。 有关如何配置函数应用设置的详细信息,请参阅管理密钥存储库中的 Key Vault 选项。 (#2048)
现在,如果共享存储帐户的多个函数应用具有相同的主机 ID,则这些应用将无法启动。 有关详细信息,请参阅主机 ID 注意事项。 (#2049)