有关 Azure Service Fabric 应用程序设计的最佳做法

本文提供有关在 Azure Service Fabric 上构建应用程序和服务的最佳做法指导。

熟悉 Service Fabric

应用程序设计指导

熟悉 Service Fabric 应用程序的一般体系结构及其设计注意事项

选择 API 网关

使用与后端服务通信的 API 网关服务,这些后端服务随后可以进行横向扩展。最常用的 API 网关服务如下:

无状态服务

我们建议,一开始始终使用可在 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/SubAzure 服务总线
  • 使执行组件状态尽可能细粒度
  • 管理执行组件的生命周期。 如果你不再使用执行组件,请将其删除。 使用易失性状态提供程序时,删除不需要的执行组件尤为重要,因为所有状态存储在内存中。
  • 最好是将执行组件用作独立的对象,因为它们采用基于轮次的并发。 不要创建多执行组件同步方法调用(每个调用很有可能会成为独立的网络调用)的图或创建循环执行组件请求, 这会对性能和规模造成显著影响。
  • 不要将同步代码和异步代码混合使用。 始终使用异步代码,以防止出现性能问题。
  • 不在在执行组件中发出长时间运行的调用。 长时间运行的调用会阻止对同一执行组件发出其他调用,因为执行组件采用基于轮次的并发。
  • 如果使用 Service Fabric 远程处理来与其他服务通信,并且你正在创建 ServiceProxyFactory,请在执行组件服务级别而不是执行组件级别创建工厂。

应用程序诊断

在服务调用中添加应用程序日志记录时应该面面俱到。 日志记录有助于诊断服务相互调用的方案。 例如,如果 A 调用 B,B 调用 C,C 调用 D,则调用可能会在任何一个位置失败。 如果没有足够的日志,将难以诊断。 如果服务记录的日志过多(因为调用量很大),请确保至少记录错误和警告。