可靠 Azure Functions 的最佳做法
Azure Functions 是事件驱动、按需计算的体验,可以扩展现有的 Azure 应用服务应用程序平台,能够实现由 Azure、第三方服务和本地系统中发生的事件触发的代码。 Functions 使你可以通过连接到数据源或消息传递解决方案来构建解决方案,从而更轻松地处理和响应事件。 Functions 在 Azure 数据中心上运行,这些数据中心包含许多集成组件,因此非常复杂。 在托管的云环境中,预计 VM 偶尔会重启或移动,并且会发生系统升级。 函数应用还可能依赖于外部 API、Azure 服务和其他数据库,而这些依赖项也很容易出现周期性的不可靠性问题。
本文详细介绍了有关设计和部署在基于云的环境中保持正常状态和良好性能的高效函数应用的一些最佳做法。
选择正确的托管计划
在 Azure 中创建函数应用时,必须为应用选择托管计划。 选择的计划会影响性能、可靠性和成本。 下面是 Azure Functions 提供的托管计划:
在应用服务平台的上下文中,用于动态托管函数的高级计划为弹性高级计划 (EP)。 还有其他一些称为高级计划的专用(应用服务)计划。 有关详细信息,请参阅高级计划一文。
选择的托管计划决定了以下行为:
- 如何根据需求缩放函数应用,以及如何管理实例分配。
- 每个函数应用实例可用的资源。
- 对 Azure 虚拟网络连接等高级功能的支持。
若要详细了解如何选择正确的托管计划以及不同计划的详细比较,请参阅 Azure Functions 托管选项。
创建函数应用时,选择正确的计划非常重要。 Functions 提供受限的功能用于切换托管计划(主要是在消耗计划和弹性高级计划之间切换)。 有关详细信息,请参阅计划迁移。
正确配置存储
Functions 需要一个与函数应用关联的存储帐户。 存储帐户连接由 Functions 主机用来执行各种操作,例如管理触发器和记录函数执行。 在动态缩放函数应用时,也会使用该连接。 有关详细信息,请参阅 Azure Functions 的存储注意事项。
在函数应用中错误地配置文件系统或存储帐户可能会影响函数的性能和可用性。 有关对错误配置的存储帐户进行故障排除的帮助,请参阅存储故障排除一文。
存储连接设置
动态缩放的函数应用可以从存储帐户中的 Azure 文件存储终结点运行,也可以从与横向扩展的实例关联的文件服务器运行。 此行为由以下应用程序设置进行控制:
仅当在 Windows 上的高级计划或消耗计划中运行时,才支持这些设置。
在 Azure 门户中或者使用 Azure CLI 或 Azure PowerShell 创建函数应用时,系统会根据需要为函数应用创建这些设置。 从 Azure 资源管理器模板(ARM 模板)创建资源时,还需要在模板中包含 WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
。
使用 ARM 模板进行首次部署时,请不要包含 WEBSITE_CONTENTSHARE
,因为系统会生成它。
可以使用以下 ARM 模板示例来帮助正确配置这些设置:
存储帐户配置
创建函数应用时,必须创建或链接到支持 Blob、队列和表存储的常规用途的 Azure 存储帐户。 Functions 依赖于 Azure 存储来执行管理触发器和记录函数执行等操作。 在 AzureWebJobsStorage
和 WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
应用程序设置中可以找到函数应用的存储帐户连接字符串。
创建此存储帐户时请注意以下事项:
为了减少延迟,请在函数应用所在的同一区域中创建存储帐户。
为了提高生产环境中的性能,请为每个函数应用使用不同的存储帐户。 对于 Durable Functions 和事件中心触发的函数尤其如此。
对于事件中心触发的函数,请不要使用启用了 Data Lake Storage 的帐户。
处理大型数据集
在 Linux 上运行时,可以通过装载文件共享来添加额外的存储。 装载共享可以方便地使函数处理现有的大型数据集。 有关详细信息,请参阅装载文件共享。
组织函数
你可能会开发并发布多个函数作为解决方案的一部分。 这些函数通常组合到单个函数应用中,但也可以分别在多个函数应用中运行。 在高级和专用(应用服务)托管计划中,多个函数应用也可以通过在同一计划中运行来共享相同的资源。 函数和函数应用的分组方式会影响整个解决方案的性能、缩放、配置、部署和安全性等方面。
对于消耗和高级计划,函数应用中的所有函数将一起动态缩放。
有关如何组织函数的详细信息,请参阅函数组织最佳做法。
优化部署
部署函数应用时,请务必记住,Azure 中函数的部署单位是函数应用。 函数应用中的所有函数将同时部署,它们通常来自同一个部署包。
要成功完成部署,请考虑采取以下做法:
使函数从部署包运行。 这种从包运行的方法具有以下优点:
- 减少文件副本锁定问题的风险。
- 可以直接部署到生产应用,从而触发重启。
- 知道包中的所有文件都可用于你的应用。
- 提高 ARM 模板部署性能。
- 可以减少冷启动时间,特别是对于具有大型 npm 包树的 JavaScript 函数。
对于高级计划托管,请考虑添加预热触发器,以便在添加新实例时减少延迟。 有关详细信息,请参阅 Azure Functions 预热触发器。
若要最大限度地减少部署故障时间并能够回退部署,请考虑使用部署槽位。 若要了解详细信息,请参阅 Azure Functions 部署槽位。
编写可靠的函数
编写有助于在一般情况下保持函数性能和可用性的函数代码时,可以遵循几项设计原则。 这些原则包括:
由于暂时性故障在云计算中很常见,因此在访问基于云的资源时,应使用重试模式。 许多触发器和绑定已实现重试。
安全设计
最好是在规划阶段而不是在函数准备就绪后考虑安全因素。 若要了解如何安全开发和部署函数,请参阅保护 Azure Functions。
考虑并发
随着对函数应用的需求因传入事件的增加而不断累积,在消耗和高级计划中运行的函数应用会横向扩展。必须了解函数应用如何响应负载,以及如何配置触发器来处理传入事件。 有关一般概述,请参阅 Azure Functions 中事件驱动的缩放。
专用(应用服务)计划要求为函数应用横向扩展做好准备。
工作进程计数
在某些情况下,横向扩展之前在实例中创建多个进程(称为语言工作进程)可以更有效地处理负载。允许的最大语言工作进程数由 FUNCTIONS_WORKER_PROCESS_COUNT 设置进行控制。 此设置的默认值为 1
,这意味着不使用多个进程。 达到最大进程数后,函数应用将横向扩展为更多实例以处理负载。 此设置不适用于在主机进程中运行的 C# 类库函数。
在高级计划或专用(应用服务)计划上使用 FUNCTIONS_WORKER_PROCESS_COUNT
时,请注意计划提供的核心数。 例如,高级计划 EP2
提供两个核心,因此应从 2
值开始,然后根据需要增加两个核心,直到达到最大数目。
触发器配置
规划吞吐量和缩放时,必须了解不同类型的触发器如何处理事件。 某些触发器允许控制批处理行为和管理并发。 调整这些选项中的值往往有助于每个实例根据被调用函数的需求适当缩放。 这些配置选项将应用于函数应用中的所有触发器,并在应用的 host.json 文件中进行维护。 有关设置详细信息,请参阅具体触发器参考文章的“配置”部分。
若要详细了解 Functions 如何处理消息流,请参阅 Azure Functions 可靠事件处理。
规划连接
在消耗计划中运行的函数应用存在连接限制。 这些限制是按实例强制实施的。 由于这些限制并根据一般最佳做法,你应该从函数代码优化出站连接。 有关详细信息,请参阅管理 Azure Functions 中的连接。
特定于语言的注意事项
对于选择的语言,请注意以下事项:
使用取消标记(仅限进程内)。
最大化可用性
冷启动是无服务器体系结构的重要考虑因素。 有关详细信息,请参阅冷启动。 如果冷启动是方案的考虑因素,可以在了解无服务器冷启动文章中找到更深入的信息。
高级计划是在保持动态缩放能力的同时减少冷启动次数的建议计划。 可以使用以下指导来减少冷启动次数并提高所有三个托管计划中的可用性。
计划 | 指南 |
---|---|
高级计划 | • 在函数应用中实现预热触发器 • 设置始终就绪实例和最大突发限制的值 • 在虚拟网络上使用非 HTTP 触发器时使用虚拟网络触发器支持 |
专用计划 | • 在启用了 Azure 应用服务运行状况检查的至少两个实例上运行 • 实现自动缩放 |
消耗计划 | • 查看对绑定和触发器使用的单一实例模式和并发设置,避免人为地对函数应用的缩放方式施加限制。 • 查看可能会限制横向扩展的 functionAppScaleLimit 设置• 在开发和测试期间检查设置的每日使用配额 (GB-Sec) 限制。 考虑在生产环境中消除此限制。 |
有效监视
Azure Functions 提供与 Azure Application Insights 的内置集成,以监视函数执行以及从代码写入的跟踪。 若要了解详细信息,请参阅监视 Azure Functions。 Azure Monitor 还提供用于监视函数应用本身运行状况的工具。 若要了解详细信息,请参阅使用 Azure Monitor 进行监视。
使用 Application Insights 集成来监视函数时,应注意以下事项:
确保已删除 AzureWebJobsDashboard 应用程序设置。 旧版 Functions 中支持此设置。 如果存在
AzureWebJobsDashboard
,将其删除可以提高函数的性能。查看 Application Insights 日志。 如果你需要查找的数据缺失,请考虑调整采样设置,以便更好地捕获监视方案。 可以使用
excludedTypes
设置从采样中排除某些类型,例如Request
或Exception
。 若要了解详细信息,请参阅配置采样。
使用 Azure Functions,还可以将系统生成的日志和用户生成的日志发送到 Azure Monitor 日志。 与 Azure Monitor 日志的集成目前以预览版提供。
内置冗余
你的业务需求可能要求即使在数据中心服务中断期间,函数也始终保持可用。 若要了解如何使用多区域方法来使关键函数始终保持运行,请参阅 Azure Functions 异地灾难恢复和高可用性。