Azure Functions 开发人员指南

在 Azure Functions 中,特定函数共享一些核心技术概念和组件,不受所用语言或绑定限制。 跳转学习某个特定语言或绑定的详细信息之前,请务必通读此通用概述。

本文假定你已阅读 Azure Functions 概述

函数代码

函数是 Azure Functions 的基本概念。 函数包含两个重要部分,即可以用各种语言编写的代码,以及一些配置,function.json 文件。 对于编译语言,此配置文件是从代码中的注释自动生成的。 对于脚本语言,必须自己提供配置文件。

Function.json 文件定义函数触发器、绑定和其他配置设置。 每个函数有且只有一个触发器。 运行时使用此配置文件确定要监视的事件,以及如何将数据传入函数执行和从函数执行返回数据。 下面是一个示例 function.json 文件。

{
    "disabled":false,
    "bindings":[
        // ... bindings here
        {
            "type": "bindingType",
            "direction": "in",
            "name": "myParamName",
            // ... more depending on binding
        }
    ]
}

有关详细信息,请参阅 Azure Functions 触发器和绑定概念

bindings 属性配置两个触发器和绑定。 每个绑定共享一些通用设置和一些特定于个别类型的绑定的设置。 每个绑定都需要以下设置:

属性 类型 注释
type 绑定名称。

例如,queueTrigger
string
direction in, out string 表示绑定是用于接收数据到函数中或是从函数发送数据。
name 函数标识符。

例如,myQueue
string 将用于函数中绑定数据的名称。 对于 C#,它将是参数名称;对于 JavaScript,它是键/值列表中的键。

函数应用

函数应用在 Azure 中提供用于运行函数的执行上下文。 因此,它是函数的部署和管理单元。 函数应用由一个或多个共同管理、部署和缩放的独立函数组成。 函数应用中的所有函数共享相同的定价计划、部署方法和运行时版本。 将函数应用视为组织和共同管理函数的一种方法。 若要了解详细信息,请参阅如何管理函数应用

注意

函数应用中的所有函数必须使用相同的语言编写。 在 Azure Functions 运行时的先前版本中,这不是必需的。

文件夹结构

特定函数应用中所有函数的代码均位于包含主机配置文件的根项目文件夹中。 host.json 文件包含特定于运行时的配置,并位于函数应用的根文件夹中。 bin 文件夹包含函数应用所需的包和其他库文件。 函数应用所需的特定文件夹结构因语言而异:

在 2.x 版及更高版本的 Functions 运行时中,函数应用中的所有函数必须共享同一语言堆栈。

以上是 Function app 的默认(和推荐)文件夹结构。 如果要更改函数代码的文件位置,请修改 function.json 文件的 scriptFile 部分。 我们还建议使用包部署将项目部署到 Azure 中的函数应用。

注意

如果手动部署包,请确保将 host.json 文件和函数文件夹直接部署到 文件夹。 请勿在部署中包含 wwwroot 文件夹。 否则,最后将得到 wwwroot\wwwroot 文件夹。

使用本地工具和发布

可以使用各种工具创作和发布各种函数应用,包括 Visual StudioVisual Studio CodeIntelliJEclipseAzure Functions Core Tools。 有关详细信息,请参阅在本地对 Azure Functions 进行编码和测试

如何编辑 Azure 门户中的函数

通过 Azure 门户中内置的函数编辑器可直接内联更新代码和 function.json 文件。 建议仅用于小的更改或概念证明 - 最佳做法是使用 VS Code 等本地开发工具。

并行执行

多个触发事件发生的速度超过了单线程函数运行的处理速度时,运行时可并行多次调用函数。 如果 Function App 正在使用消耗量托管计划,则 Function App 可自动扩大。 无论应用是在消耗量托管计划还是常规应用服务托管计划上运行,每个 Function App 实例都可能使用多个线程并行处理并发函数调用。 每个 Function App 实例中并发函数的最大调用数根据所用触发器类型以及 Function App 中其他函数所用资源而有所不同。

Functions 运行时版本控制

可使用 FUNCTIONS_EXTENSION_VERSION 应用设置配置 Functions 运行时的版本。 例如,值“~3”表示函数应用将使用 3.x 作为其主版本。 函数应用在发布后,将升级到各个新的次要版本。 有关详细信息(包括如何查看函数应用的确切版本),请参阅如何针对 Azure Functions 运行时版本

存储库

Azure Functions 代码为开放源,位于 GitHub 存储库:

绑定

下面是所有受支持的绑定表。

下表显示了 Azure Functions 运行时的主版本支持的绑定:

类型 1.x 2.x 及更高版本1 触发器 输入 输出
Blob 存储
Azure Cosmos DB
Azure SQL(预览版)
Dapr3
事件网格
事件中心
HTTP 和 Webhook
IoT 中心
Kafka2
移动应用
通知中心
队列存储
RabbitMQ2
SendGrid
服务总线
SignalR
表存储
计时器

1 从版本 2.x 运行时开始,除了 HTTP 和 Timer 以外,所有绑定都必须注册。 请参阅注册绑定扩展

2 消耗计划中不支持触发器。 需要运行时驱动的触发器

3 仅支持 Kubernetes、IoT Edge 和其他自托管模式。

对来自绑定的错误怀有疑问? 请查看 Azure Functions 绑定错误代码文档。

连接

函数项目从其配置提供程序按名称引用连接信息。 它不直接接受连接详细信息,而是允许跨环境对其进行更改。 例如,触发器定义可能包括 connection 属性。 这可能是指连接字符串,但不能直接在 function.json 中设置连接字符串。 相反,应将 connection 设置为包含连接字符串的环境变量的名称。

默认配置提供程序使用环境变量。 在 Azure Functions 服务中运行时,可以通过应用程序设置进行设置,而在本地开发时,可以通过本地设置文件进行设置。

连接值

当连接名称解析为单个精确值时,运行时会将值标识为通常包含机密的连接字符串。 连接字符串的详细信息由你要连接到的服务定义。

但是,连接名称也可以引用多个配置项目的集合,这可用于配置基于标识的连接。 可以通过使用以双下划线 __ 结尾的共享前缀将环境变量视为集合。 然后,可以通过将连接名称设置为此前缀来引用该组。

例如,Azure Blob 触发器定义的 connection 属性可能是“Storage1”。 只要名为“Storage1”的环境变量没有配置单个字符串值,就可以使用名为 Storage1__blobServiceUri 的环境变量来通知连接的 blobServiceUri 属性。 每个服务的连接属性各不相同。 请参阅相关文档,了解使用连接的组件。

注意

使用 Azure 应用程序配置Key Vault 为托管标识连接提供设置时,设置名称应使用有效的键分隔符(例如 :/)替代 __,以确保正确解析名称。

例如 Storage1:blobServiceUri

配置基于标识的连接

Azure Functions 中的某些连接配置为使用标识而不是机密。 支持取决于使用连接的扩展。 在某些情况下,即使连接到的服务支持基于标识的连接,Functions 中仍可能需要连接字符串。 有关使用托管标识配置函数应用的教程,请参阅使用基于标识的连接创建函数应用教程

以下组件支持基于标识的连接:

连接源 支持的计划 了解更多
Azure Blob 触发器和绑定 全部 扩展 5.0.0 或更高版本
Azure 队列触发器和绑定 全部 扩展 5.0.0 或更高版本
Azure 事件中心触发器和绑定 全部 扩展 5.0.0 或更高版本
Azure 服务总线触发器和绑定 全部 扩展 5.0.0 或更高版本
Azure Cosmos DB 触发器和绑定 - 预览 弹性高级计划 扩展版本 4.0.0-preview1 或更高版本
Azure 表(使用 Azure 存储时)- 预览版 All 表 API 扩展
Durable Functions 存储提供程序(Azure 存储)- 预览版 全部 扩展 2.7.0 或更高版本
主机所需存储(“AzureWebJobsStorage”)- 预览 全部 使用标识连接到主机存储

在 Azure Functions 服务中托管时,基于标识的连接将使用托管标识。 默认情况下使用系统分配的标识,但可以使用 credentialclientID 属性来指定用户分配的标识。 在其他上下文(如本地开发)中运行时,将改用开发人员标识,尽管可以进行自定义。 请参阅使用基于标识的连接进行本地开发

向标识授予权限

无论使用何种标识,都必须具有执行所需操作的权限。 需要使用内置角色或者提供这些权限的自定义角色在 Azure RBAC 中分配角色

重要

某些权限可能由并非所有上下文都需要的目标服务公开。 尽可能遵循最低权限原则,仅授予标识所需的权限。 例如,如果应用只需要从数据源进行读取即可,则使用仅具有读取权限的角色。 分配一个也具有该服务写入权限的角色并不恰当,因为对于读取操作来说,写入是多余的权限。 同样,你也希望确保角色分配的范围仅限于需要读取的资源。

选择下面的选项卡以了解每个组件的权限:

你将需要创建一个角色分配,以便在运行时提供对 Blob 容器的访问权限。 所有者等管理角色还不够。 下表显示了在正常操作中使用 Blob 存储扩展时建议使用的内置角色。 根据所编写的代码,应用程序可能需要具有其他权限。

绑定类型 内置角色示例
触发器 存储 Blob 数据所有者存储队列数据参与者1

此外,还必须为 AzureWebJobsStorage 连接授予其他权限。2
输入绑定 存储 Blob 数据读者
输出绑定 存储 Blob 数据所有者

1 Blob 触发器通过将有害 blob 写入到连接所指定的存储帐户上的队列来处理多次重试中出现的故障。

2 AzureWebJobsStorage 连接在内部用于启用触发器的 blob 和队列。 如果将其配置为使用基于标识的连接,则该连接将需要超出默认要求的其他权限。 存储 Blob 数据所有者存储队列数据参与者存储帐户参与者角色涵盖了这些权限。 若要了解详细信息,请参阅使用标识连接到主机存储

基于标识的连接的通用属性

Azure 服务的基于标识的连接接受以下通用属性,其中 <CONNECTION_NAME_PREFIX> 是触发器或绑定定义中 connection 属性的值:

属性 环境变量模板 说明
令牌凭据 <CONNECTION_NAME_PREFIX>__credential 定义如何为连接获取令牌。 建议仅在指定用户分配的标识时使用,此时它应设置为“managedidentity”。 仅当在 Azure Functions 服务中托管时,此属性才有效。
客户端 ID <CONNECTION_NAME_PREFIX>__clientId credential 设置为“managedidentity”时,此属性指定在获取令牌时要使用的用户分配的标识。 该属性接受与分配给应用程序的用户分配的标识对应的客户端 ID。 如果未指定,则将使用系统分配的标识。 在本地开发方案中使用时,此属性的使用方式不同,且不应设置

给定的连接类型可能支持其他选项。 请参阅相关文档,了解用于建立连接的组件。

使用基于标识的连接进行本地开发

注意

使用基于标识的连接进行本地部署需要更新版本的 Azure Functions Core Tools。 可以通过运行 func -v 来检查当前安装的版本。 对于 Functions v3,请使用版本 3.0.3904 或更高版本。 对于 Functions v4,请使用版本 4.0.3904 或更高版本。

在本地运行时,上述配置会告知运行时使用本地开发人员标识。 连接将尝试从以下位置获取令牌,顺序如下:

  • Microsoft 应用程序之间共享的本地缓存
  • Visual Studio 中的当前用户上下文
  • Visual Studio Code 中的当前用户上下文
  • Azure CLI 中的当前用户上下文

如果这些选项都不成功,则会出现错误。

你的标识可能已针对用于开发的 Azure 资源完成了一些角色分配,但这些角色可能不提供必需的数据访问权限。 所有者等管理角色是不够的。 仔细检查每个组件的连接所需的权限,并确保已将它们分配给自己。

在某些情况下,你可能希望指定使用其他标识。 可以根据 Azure Active Directory 服务主体的客户端 ID 和客户端密码为指向备用标识的连接添加配置属性。 在 Azure Functions 服务中托管时,不支持此配置选项。 若要在本地计算机上使用 ID 和机密,请使用以下附加属性定义连接:

属性 环境变量模板 说明
租户 ID <CONNECTION_NAME_PREFIX>__tenantId Azure Active Directory 租户(目录)ID。
客户端 ID <CONNECTION_NAME_PREFIX>__clientId 租户中应用注册的客户端(应用程序)ID。
客户端机密 <CONNECTION_NAME_PREFIX>__clientSecret 为应用注册生成的客户端密码。

以下是基于标识的 Azure Blob 连接所需的 local.settings.json 属性示例:

{
  "IsEncrypted": false,
  "Values": {
    "<CONNECTION_NAME_PREFIX>__blobServiceUri": "<blobServiceUri>",
    "<CONNECTION_NAME_PREFIX>__queueServiceUri": "<queueServiceUri>",
    "<CONNECTION_NAME_PREFIX>__tenantId": "<tenantId>",
    "<CONNECTION_NAME_PREFIX>__clientId": "<clientId>",
    "<CONNECTION_NAME_PREFIX>__clientSecret": "<clientSecret>"
  }
}

使用标识连接到主机存储(预览)

对于核心行为(例如协调计时器触发器的单一实例执行)和默认应用密钥存储,Azure Functions 主机使用“AzureWebJobsStorage”连接。 这也可以配置为利用标识。

注意

Functions 中的其他组件依赖于“AzureWebJobsStorage”的默认行为。 如果使用的是不支持此类连接的旧版本扩展(包括 Azure Blob、事件中心和 Durable Functions 的触发器和绑定),则不应将其移动到基于标识的连接。 同样,在 Linux 消耗计划中使用服务器端内部版本时,AzureWebJobsStorage 用于部署项目,并且,如果你启用此项,则将需要通过AzureWebJobsStorage来进行部署。

此外,某些应用程序在其触发器、绑定和/或函数代码中将“AzureWebJobsStorage”重用于其他存储连接。 请确保在从连接字符串中更改此连接之前,所有使用“AzureWebJobsStorage”的情形都能够使用基于标识的连接格式。

若要将基于标识的连接用于“AzureWebJobsStorage”,请配置以下应用设置:

设置 说明 示例值
AzureWebJobsStorage__blobServiceUri 存储帐户的 blob 服务的数据平面 URI,使用 HTTPS 方案。 https://<storage_account_name>.blob.core.chinacloudapi.cn
AzureWebJobsStorage__queueServiceUri 存储帐户的队列服务的数据平面 URI,使用 HTTPS 方案。 https://<storage_account_name>.queue.core.chinacloudapi.cn
AzureWebJobsStorage__tableServiceUri 存储帐户的表服务的数据平面 URI,使用 HTTPS 方案。 https://<storage_account_name>.table.core.chinacloudapi.cn

还可以设置基于标识的连接的通用属性

如果配置“AzureWebJobsStorage”时使用的存储帐户将默认 DNS 后缀和服务名称用于全局 Azure,则可以按照 https://<accountName>.blob/queue/file/table.core.chinacloudapi.cn 格式将 AzureWebJobsStorage__accountName 设置为存储帐户的名称。 将为此帐户推断每个存储服务的终结点。 如果存储帐户在主权云中或具有自定义 DNS,则此操作不起作用。

设置 说明 示例值
AzureWebJobsStorage__accountName 存储帐户的帐户名称,仅当帐户不在主权云中且没有自定义 DNS 时有效。 此语法是“AzureWebJobsStorage”独有的,不能用于其他基于标识的连接。 <storage_account_name>

你将需要创建一个角色分配,以便在运行时提供对“AzureWebJobsStorage”存储帐户的访问权限。 所有者等管理角色还不够。 存储 Blob 数据所有者角色涵盖了 Functions 主机存储的基本需求 - 运行时需要具有对 Blob 的读写访问权限以及创建容器的能力。 多个扩展使用此连接作为 blob、队列和表的默认位置,此类用法可能会添加下表所述要求。 如果将“AzureWebJobsStorage”用于任何其他目的,可能需要其他权限。

分机 所需角色 说明
没有扩展(仅主机) 存储 Blob 数据所有者 用于常规协调,默认密钥存储
Azure Blob(仅触发器) 所有:
存储帐户参与者
存储 Blob 数据所有者
存储队列数据参与者
blob 触发器在内部使用 Azure 队列并写入 blob 回执。 无论为触发器配置的连接如何,它都会使将 AzureWebJobsStorage 用于这些项。
Azure 事件中心(仅触发器) (没有默认要求中的更改)
存储 Blob 数据所有者
使用 AzureWebJobsStorage 连接将检查点保存在 blob 中。
计时器触发器 (没有默认要求中的更改)
存储 Blob 数据所有者
若要确保每个事件执行一次,请使用 AzureWebJobsStorage 连接对 blob 进行锁定。
Durable Functions N/A1 Durable Functions 使用 blob、队列和表来协调活动函数和保持业务流程状态。 默认情况下,它将 AzureWebJobsStorage 连接用于所有这些项,但你可以在 Durable Functions 扩展配置中指定另一连接。

1 Durable Functions 目前不支持基于标识的连接。 若要为 AzureWebJobsStorage 配置基于标识的连接,必须在 Durable Functions 扩展配置中指定不同于 AzureWebJobsStorage 的连接。

报告问题

说明 链接
运行时 脚本主机、触发器和绑定、语言支持 提出问题
模板 创建模板的代码问题 提出问题
门户 用户界面或体验问题 提出问题

后续步骤

有关详细信息,请参阅以下资源: