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\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
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__serviceUri 就会用于连接的 serviceUri 属性。 每个服务的连接属性各不相同。 请参阅相关文档,了解使用连接的扩展。

配置基于标识的连接

Azure Functions 中的某些连接配置为使用标识而不是机密。 支持取决于使用连接的扩展。 在某些情况下,即使连接到的服务支持基于标识的连接,Functions 中仍可能需要连接字符串。

所有计划中的以下触发器和绑定扩展支持基于标识的连接:

备注

Durable Functions 不支持基于标识的连接。

扩展名称 扩展版本
Azure Blob 版本 5.0.0-beta1 或更高版本
Azure 队列 版本 5.0.0-beta1 或更高版本
Azure 事件中心 版本 5.0.0-beta1 或更高版本
Azure 服务总线 版本 5.0.0-beta2 或更高版本

还可以使用基于标识的连接来配置 Functions 运行时 (AzureWebJobsStorage) 所用的存储连接。 请参阅下面的使用标识连接到主机存储

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

向标识授予权限

无论使用何种标识,都必须具有执行所需操作的权限。 这通常是通过在 Azure RBAC 中分配角色或在访问策略中指定标识来完成的,具体取决于要连接到的服务。 请参阅每个扩展的文档,了解需要哪些权限以及如何设置这些权限。

重要

某些权限可能由并非所有上下文都需要的目标服务公开。 尽可能遵循最低权限原则,仅授予标识所需的权限。 例如,如果应用只需从 Blob 读取数据,请使用存储 Blob 数据读取者角色,因为存储 Blob 数据所有者包含过多的读取操作权限。 以下角色涵盖正常操作中每个扩展所需的主要权限:

服务 内置角色示例
Azure Blob 存储 Blob 数据读取器存储 Blob 数据所有者
Azure 队列 存储队列数据读取器存储队列数据消息处理器存储队列数据消息发送方存储队列数据参与者
事件中心 Azure 事件中心数据接收方Azure 事件中心数据发送方Azure 事件中心数据所有者
服务总线 Azure 服务总线数据接收方Azure 服务总线数据发送方Azure 服务总线数据所有者

连接属性

Azure 服务的基于标识的连接接受以下属性:

属性 扩展所需 环境变量 说明
服务 URI Azure Blob1、Azure 队列 <CONNECTION_NAME_PREFIX>__serviceUri 要连接到的服务的数据平面 URI。
完全限定的命名空间 事件中心、服务总线 <CONNECTION_NAME_PREFIX>__fullyQualifiedNamespace 完全限定的事件中心和服务总线命名空间。
令牌凭据 (可选) <CONNECTION_NAME_PREFIX>__credential 定义如何为连接获取令牌。 建议仅在指定用户分配的标识时使用,此时它应设置为“managedidentity”。 仅当在 Azure Functions 服务中托管时,此属性才有效。
客户端 ID (可选) <CONNECTION_NAME_PREFIX>__clientId credential 设置为“managedidentity”时,此属性指定在获取令牌时要使用的用户分配的标识。 该属性接受与分配给应用程序的用户分配的标识对应的客户端 ID。 如果未指定,则将使用系统分配的标识。 在本地开发方案中使用时,此属性的使用方式不同,且不应设置 credential

1 Azure Blob 需要 Blob URI 和队列服务 URI。

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

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

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

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

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

在某些情况下,你可能希望指定使用其他标识。 可以添加指向其他标识的连接的配置属性。

备注

在 Azure Functions 服务中托管时,不支持以下配置选项。

若要在 Azure Active Directory 服务主体中使用客户端 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>__serviceUri": "<serviceUri>",
    "<CONNECTION_NAME_PREFIX>__tenantId": "<tenantId>",
    "<CONNECTION_NAME_PREFIX>__clientId": "<clientId>",
    "<CONNECTION_NAME_PREFIX>__clientSecret": "<clientSecret>"
  }
}

使用标识连接到主机存储

默认情况下,Azure Functions 使用 AzureWebJobsStorage 连接来实现核心行为,例如协调计时器触发器和默认应用密钥存储的单一实例执行。 也可以将此连接配置为使用标识。

注意

某些应用在其触发器、绑定和/或函数代码中重复使用 AzureWebJobsStorage 进行存储连接。 在从连接字符串更改此连接之前,请确保全部所用的 AzureWebJobsStorage 都能够使用基于标识的连接格式。

若要以此方式配置连接,请确保应用的标识具有存储 Blob 数据所有者角色,以支持核心主机功能。 如果出于任何其他目的使用“AzureWebJobsStorage”,可能需要更多的权限。

如果所用的存储帐户使用全球 Azure 的默认 DNS 后缀和服务名称(遵循 https://<accountName>.blob/queue/file/table.core.chinacloudapi.cn 格式),则你可以将 AzureWebJobsStorage__accountName 设置为你的存储帐户名称。

如果改用主权云中的或者采用自定义 DNS 的存储帐户,请将 AzureWebJobsStorage__serviceUri 设置为你的 Blob 服务的 URI。 如果要对任何其他服务使用“AzureWebJobsStorage”,则可以改为分别指定 AzureWebJobsStorage__blobServiceUriAzureWebJobsStorage__queueServiceUriAzureWebJobsStorage__tableServiceUri

报告问题

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

后续步骤

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