Durable Functions 最佳做法和诊断工具
本文详细介绍了使用 Durable Functions 时的一些最佳做法。 它还介绍了各种工具,这些工具可帮助诊断开发、测试和生产使用期间的问题。
最佳做法
使用最新版本的 Durable Functions 扩展和 SDK
函数应用使用两个组件来执行 Durable Functions。 一个是 Durable Functions SDK,可用于使用目标编程语言编写业务流程协调程序、活动和实体函数。 另一个是持久扩展,它是实际执行代码的运行时组件。 除了 .NET 进程内应用外,SDK 和扩展独立进行版本控制。
随时了解最新的扩展和 SDK 可确保应用程序受益于最新的性能改进、功能和 bug 修复。 升级到最新版本还可确保 Microsoft 可以收集最新的诊断遥测数据,以帮助在向 Azure 提交支持案例时加快调查过程。
- 有关获取最新扩展版本的说明,请参阅升级 Durable Functions 扩展版本。
- 若要确保使用最新版本的 SDK,请检查所使用的语言的包管理器。
遵守 Durable Functions 代码约束
业务流程协调程序代码的重播行为针对可在业务流程协调程序函数中编写的代码类型创建约束。 约束的一个示例是,业务流程协调程序函数必须使用确定性 API,以便每次重播它时都会生成相同的结果。
注意
Durable Functions Roslyn 分析器是一个实时代码分析器,指导 C# 用户遵守 Durable Functions 特定代码约束。 有关如何在 Visual Studio 和 Visual Studio Code 上启用它的说明,请参阅 Durable Functions Roslyn 分析器。
熟悉编程语言的 Azure Functions 性能设置
使用默认设置,所选语言运行时可能会对函数施加严格的并发限制。 例如:仅允许在给定 VM 上一次执行 1 个函数。 通常可以通过微调语言的并发和性能设置来放宽这些限制。 如果要优化 Durable Functions 应用程序的性能,则需要熟悉这些设置。
下面是通常受益于微调其性能和并发设置的一些语言的非详尽列表,以及具体操作指南。
保证每个应用的任务中心名称唯一
多个持久函数应用可以共享同一存储帐户。 默认情况下,应用的名称用作任务中心名称,这可确保不会意外共享任务中心。 如果需要在 host.json 中显式配置应用的任务中心名称,则必须确保名称是唯一的。 否则,多个应用会竞争消息,这可能会导致未定义的行为,例如业务流程意外“卡”在挂起或运行中状态。
唯一例外是在多个区域部署同一应用的副本;在这种情况下,可以对副本使用相同的任务中心。
将代码更改部署到正在运行的业务流程协调程序时,请遵循指导
在应用程序的生存期内添加、删除和更改函数是不可避免的。 常见中断性变更的示例包括更改活动或实体函数签名以及更改业务流程协调程序逻辑。 当这些更改影响仍在运行的业务流程时,它们是一个问题。 如果部署不正确,代码更改可能会导致业务流程失败并出现非确定性错误、无限期停滞、性能下降等。进行可能影响正在运行的业务流程的代码更改时,请参阅建议的缓解策略。
使函数输入和输出尽可能小
如果向 Durable Functions API 提供大型输入和输出,则可能会遇到内存问题。
Durable Functions API 的输入和输出将序列化到业务流程历史记录中。 这意味着,随着时间的推移,大型输入和输出可能会极大地促进业务流程协调程序历史记录无限增长,从而有可能在重播期间导致内存异常。
为了减轻大型输入和输出对 API 的影响,可以选择将一些工作委托给子业务流程协调程序。 这有助于将历史记录内存负担从单个业务流程协调程序负载均衡到多个业务流程协调程序,从而使单个历史记录的内存占用情况保持较小。
也就是说,处理大数据的最佳做法是将其保存在外部存储中,并在需要时仅在活动内具体化该数据。 采用此方法时,可以传入一些轻量级标识符,以便在需要时在活动中从外部存储检索数据,而不是将数据本身作为 Durable Functions API 的输入和/或输出进行传达。
使实体数据保持较小
就像 Durable Functions API 的输入和输出一样,如果实体的显式状态太大,则可能会遇到内存问题。 具体而言,需要在任何请求上从存储中序列化和反序列化实体状态,因此大的状态会增加每次调用的序列化延迟。 因此,如果实体需要跟踪大数据,建议将该数据分流到外部存储,并在实体中跟踪一些轻型标识符,以便在需要时从存储中具体化数据。
微调 Durable Functions 并发设置
单个辅助角色实例可以同时执行多个工作项以提高效率。 但是,同时处理过多的工作项可能会耗尽 CPU 容量、网络连接等资源。在许多情况下,这不应成为问题,因为会自动处理缩放和限制工作项。 也就是说,如果遇到性能问题(例如业务流程协调程序完成时间过长、停滞在挂起状态等)或正在执行性能测试,则可以在 host.json 文件中配置并发限制。
注意
这不是在 Azure Functions 中微调语言运行时的性能和并发设置的替代方法。 Durable Functions 并发设置仅确定一次可以分配给给定 VM 的工作量,但不能确定 VM 内处理该工作的并行度。 后者需要微调语言运行时性能设置。
为外部事件使用唯一名称
与活动函数一样,外部事件具有至少一次传送保证。 这意味着,在某些罕见的条件下(在重启、缩放、崩溃等过程中可能会出现),应用程序可能会收到重复的同一外部事件。 因此,我们建议外部事件包含一个 ID,以便在业务流程协调程序中手动取消其重复。
注意
与默认的 Azure 存储存储提供程序不同,MSSQL 存储提供程序以事务方式使用外部事件和更新业务流程协调程序状态,因此后端应该不会有出现重复事件的风险。 也就是说,仍然建议外部事件具有唯一的名称,以便代码可以跨后端移植。
在压力测试中的投资
与任何性能相关内容一样,应用的理想并发设置和体系结构最终取决于应用程序的工作负载。 因此,建议用户投资一个性能测试工具来模拟其预期工作负载,并使用它来运行其应用的性能和可靠性试验。
避免输入、输出和异常中的敏感数据
在所选存储提供程序中,会持久保存往返 Durable Functions API 的输入和输出(包括异常)。 如果这些输入、输出或异常包含敏感数据(例如机密、连接字符串、个人身份信息等),则对存储提供程序资源具有读取访问权限的任何人都可以获取它们。 要安全地处理敏感数据,建议用户从 Azure Key Vault 或环境变量的活动函数中提取该数据 ,并且从不将这些数据直接传达给业务流程协调程序或实体。 这应该有助于阻止敏感数据泄漏到存储资源中。
注意
本指南也适用于CallHttp
业务流程协调程序 API,该 API 还会在存储中保留其请求和响应有效负载。 如果目标 HTTP 终结点需要身份验证(可能很敏感),则建议用户在活动内部实现 HTTP 调用本身,或者使用CallHttp
提供的内置托管标识支持,该支持不会将任何凭据保存到存储中。
提示
同样,避免将包含机密的数据记录为对日志具有读取访问权限的任何人(例如 Application Insights 中),可以获取这些机密。
诊断工具
有多种工具可帮助你诊断问题。
Durable Functions 和持久任务框架日志
Durable Functions 扩展
持久扩展会发出跟踪事件,用于跟踪业务流程的端到端执行。 可在 Azure 门户中使用 Application Insights Analytics 工具来查找和查询这些跟踪事件。 可以在 host.json 文件的 logger
(Functions 1.x) 或 logging
(Functions 2.0) 部分对发出的跟踪数据的详细程度进行配置。 请参阅配置详细信息。
持久任务框架
从 Durable 扩展 v2.3.0 开始,由基础 Durable Task Framework (DTFx) 发出的日志也可用于集合。 请参阅有关如何启用这些日志的详细信息。
Azure 门户
诊断并解决问题
Azure 函数应用诊断是 Azure 门户的有用资源,用于监视和诊断应用程序中的潜在问题。 它还提供建议,以帮助根据诊断解决问题。 请参阅 Azure 函数应用诊断。
Durable Functions 业务流程跟踪
Azure 门户提供了业务流程跟踪详细信息,可帮助你了解每个业务流程实例的状态并跟踪端到端执行。 查看 Azure Functions 应用中的函数列表时,你会看到一个包含指向跟踪的链接的 Monitor 列。 需要为应用启用 Application Insights 才能获取此信息。
Durable Functions Monitor 扩展
这是一个 Visual Studio Code 扩展,提供用于监视、管理和调试业务流程实例的 UI。
Roslyn 分析器
Durable Functions Roslyn 分析器是一个实时代码分析器,指导 C# 用户遵守 Durable Functions 特定代码约束。 有关如何在 Visual Studio 和 Visual Studio Code 上启用它的说明,请参阅 Durable Functions Roslyn 分析器。
支持
有关问题和支持,可以在下面的 GitHub 存储库之一中提出问题。 报告 Azure 中的 bug(包括受影响的实例 ID、显示问题的 UTC 时间范围等信息)时,应用程序名称(如果可能)和部署区域将大大加快调查速度。