有关 Azure Service Fabric 应用程序设计的最佳做法
本文提供有关在 Azure Service Fabric 上构建应用程序和服务的最佳做法指导。
熟悉 Service Fabric
- 阅读想要了解 Service Fabric?一文。
- 阅读 Service Fabric 应用程序方案。
- 在 Service Fabric 编程模型概述中了解编程模型选项。
应用程序设计指导
熟悉 Service Fabric 应用程序的一般体系结构及其设计注意事项。
选择 API 网关
使用与后端服务通信的 API 网关服务,这些后端服务随后可以进行横向扩展。最常用的 API 网关服务如下:
-
注意
Azure 应用程序网关不直接与 Service Fabric 集成。 通常首选 Azure API 管理。
自定义构建的 ASP.NET Core Web 应用程序网关。
无状态服务
我们建议,一开始始终使用可在 Azure 数据库、Azure Cosmos DB 或 Azure 存储中存储状态的 Reliable Services 构建无状态服务。 对于大多数开发人员而言,使状态外部化是他们更熟悉的方法。 此方法还可以利用存储查询功能。
何时使用有状态服务
如果你的方案要求低延迟,并需要使数据靠近计算资源,请考虑使用有状态服务。 部分示例方案包括 IoT 数字孪生设备、游戏状态、会话状态、缓存数据库中的数据,以及长时间运行的用于跟踪对其他服务的调用的工作流。
确定数据保留期限:
- 缓存的数据。 如果与外部存储之间的延迟是一个问题,请使用缓存。 将有状态服务用作自己的数据缓存,或考虑使用开源的 SoCreate Service Fabric 分布式缓存。 在此方案中,无需担心是否会丢失缓存中的所有数据。
- 时间受限的数据。 在此方案中,需要使数据靠近计算资源以减小某个时间段的延迟,但在发生灾难时,你能够承受得起丢失该数据所造成的影响。 例如,在许多 IoT 解决方案中,数据需要靠近计算资源(例如,计算过去几天的平均温度),但如果此数据丢失,则记录的特定数据点就不是那么重要。 此外,在此方案中,你通常不会关心单个数据点的备份。 你只需备份定期写入到外部存储的平均计算值。
- 长期数据。 可靠集合可以永久存储数据。 但是,在这种情况下,需要为灾难恢复做好准备,包括为群集配置定期备份策略。 实际上,配置的设置涉及到群集在灾难中受损时要怎样做、在哪种情况下需要创建新的群集、如何部署新应用程序实例以及从最新的备份恢复。
节省成本并提高可用性:
- 可以使用有状态服务降低成本,因为从远程存储执行数据访问和事务不会产生成本,并且无需使用另一个服务(例如 Azure Redis 缓存)。
- 将有状态服务主要用于存储而不是计算的做法会造成很大的成本,我们不建议这样做。 请考虑将有状态服务用作本地存储成本低廉的计算资源。
- 消除与其他服务之间的依赖关系可以提高服务可用性。 使用群集中的 HA 管理状态可以免受其他服务停机或延迟问题造成的影响。
如何使用 Reliable Services
使用 Service Fabric Reliable Services 可以轻松创建无状态和有状态服务。 有关详细信息,请参阅 Reliable Services 简介。
- 始终遵循
RunAsync()
方法(对于无状态和有状态服务)和ChangeRole()
方法(对于有状态服务)中的取消标记。 否则,Service Fabric 不知道是否可以关闭你的服务。 例如,如果你不遵循取消标记,可能会导致应用程序升级时间大幅延长。 - 及时打开和关闭通信侦听器并遵循取消标记。
- 切勿将同步代码和异步代码混合使用。 例如,不要在异步调用中使用
.GetAwaiter().GetResult()
。 在整个调用堆栈中始终使用异步调用。
如何使用 Reliable Actors
使用 Service Fabric Reliable Actors 可以轻松创建有状态的虚拟执行组件。 有关详细信息,请参阅 Reliable Actors 简介。
- 强烈建议考虑在执行组件之间使用 pub/sub 消息传送来缩放应用程序。 提供此服务的工具包括开源的 SoCreate Service Fabric Pub/Sub 和 Azure 服务总线。
- 使执行组件状态尽可能细粒度。
- 管理执行组件的生命周期。 如果你不再使用执行组件,请将其删除。 使用易失性状态提供程序时,删除不需要的执行组件尤为重要,因为所有状态存储在内存中。
- 最好是将执行组件用作独立的对象,因为它们采用基于轮次的并发。 不要创建多执行组件同步方法调用(每个调用很有可能会成为独立的网络调用)的图或创建循环执行组件请求, 这会对性能和规模造成显著影响。
- 不要将同步代码和异步代码混合使用。 始终使用异步代码,以防止出现性能问题。
- 不在在执行组件中发出长时间运行的调用。 长时间运行的调用会阻止对同一执行组件发出其他调用,因为执行组件采用基于轮次的并发。
- 如果使用 Service Fabric 远程处理来与其他服务通信,并且你正在创建
ServiceProxyFactory
,请在执行组件服务级别而不是执行组件级别创建工厂。
应用程序诊断
在服务调用中添加应用程序日志记录时应该面面俱到。 日志记录有助于诊断服务相互调用的方案。 例如,如果 A 调用 B,B 调用 C,C 调用 D,则调用可能会在任何一个位置失败。 如果没有足够的日志,将难以诊断。 如果服务记录的日志过多(因为调用量很大),请确保至少记录错误和警告。