防故障:弹性云体系结构的指南

更新时间: 2014年6月

作者:Marc Mercuri、Ulrich Homann、Mark Simms、Jason Wescott 和 Andrew Townhill

审阅者:Michael Thomassy、Curt Peterson、Stuart Ozer、Fran Dougherty、Tim O’Brien、Hatay Tuna、Patrick Butler Monterde、Mark Kottke、Lewis Curtis、William Bellamy

发布日期:2014 年 6 月

防故障 (名词):设计为自动工作或作用,以防止机制、系统或类似对象发生崩溃的某种措施。

任何人 - 无论是指员工、公民还是消费者,他们都需要即时访问应用程序、计算和数据服务。连接到这些服务的用户以及设备的数量在不断增加。对于这些需要始终保持运行的服务,支持它们的系统必须设计为具有高可用性和弹性。

这些服务将在预定义配置中填充了商品的云环境中部署。从历史上看,你可能已购买高端硬件以向上扩展;但在云环境中,你必须改为向外扩展。你可以使用商用硬件来保持这些云环境的成本较低。商用硬件会发生故障,因此云要求体系结构真正接受故障。从历史上看,你可能已将重点放在防止发生故障和优化“平均故障间隔时间”。在此新环境中,重点将转移到优化“影响最小时的平均还原时间”。

很有可能你开发的服务将是复合服务。这些服务将由一个或多个第一方或第三方平台和第三方提供商服务组成。这些服务将基于可能会发生故障的云基础结构构建。该体系结构也必须假定它们使用的服务也会发生故障。与基础结构体系结构一样,应用程序体系结构设计必须接受故障。

Microsoft 提出的“防故障”倡议旨在提供构建弹性云体系结构,以及利用 Microsoft 技术实现这些体系结构的一般性指南,还提供了针对特定应用场景实现这些体系结构的方法。本文档的作者是 Microsoft 的 Cloud + 企业部可信任计算和 Microsoft 咨询服务的成员。

本文档侧重介绍在设计可扩展的弹性系统时需要考虑的体系结构方面的事项。

本文分为以下章节:

  • 按工作负荷分解应用程序:解释为什么说以工作负荷为中心的方法能够更好地控制成本,能够更加灵活地选择最适合工作负荷的技术,以及能够以一种更为精细可调的方式实现可用性和弹性。

  • 建立生命周期模型:建立应用程序生命周期模型可以帮助定义应用程序在生产中的预期行为,并提供总体体系结构的要求和有关它的见解。

  • 建立可用性模型和规划:可用性模型用于确定你的工作负荷所要求的可用性级别。这很关键,因为它决定了你在构建服务时要做出的很多决策。

  • 确定故障点、故障模式和故障影响:若要创建弹性体系结构,需要了解和确定故障点以及故障模式。具体而言,就是主动采取一些措施来了解和记录可能导致停机的因素,并建立一个大纲,以便在分析和规划中使用。

  • 弹性模式和注意事项:本节是文档的主体内容,包含与计算、存储和平台服务有关的重要事项。这些注意事项重点介绍了有关计算、存储和平台服务等方面的一些行之有效的做法,以帮助用户交付合格的应用程序。

  • 针对运行状况的设计:在要求服务“始终保持运行”的环境中,针对运行状况来设计服务很重要。本节介绍了在整个生命周期内针对运行状况进行设计的经过验证的做法,包括建立运行状况模型来实现遥测,并将这些遥测信息以可视化方式呈现给运营和开发人员。

应用程序通常包含多个工作负荷。

不同的工作负荷通常具有不同的要求,根据工作负荷对业务的重要性的不同,与之关联的财务支持也不同。通过将应用程序分解为工作负荷,组织可以获得对自身很重要的灵活性。以工作负荷为中心的方法可以更好地控制成本,可以更灵活地选择最适合工作负载的技术,以及提供工作负荷特定的方法来实现可用性和安全性并灵活添加和部署新功能等。

在考虑弹性时,有时需要结合应用场景来考虑。以下是一些典型的应用场景示例:

  • 体育运动数据服务

    有一家客户提供体育运动信息方面的数据服务。该服务有两个主要工作负荷。第一个工作负荷提供球员和球队的统计信息。第二个工作负荷提供当前正在进行的比赛的比分和实况报道。

  • 电子商务网站

    一家网上零售商通过一个建制完善的网站销售商品。该应用程序具有很多工作负荷,最常用的功能是“搜索和浏览”以及“结帐”。

  • 社交

    一个知名度高的社交网站允许社区成员通过论坛分享自己的亲身经历、发布用户生成的内容以及玩玩休闲小游戏。该应用程序具有很多工作负荷,包括注册、搜索和浏览、社交互动、游戏、电子邮件等。

  • Web

    一个组织希望通过网站向客户提供体验。该应用程序需要在基于 PC 的浏览器和常见移动设备类型(手机、平板电脑)上提供体验。该应用程序同样具有很多工作负荷,包括注册、搜索和浏览、内容发布、社交评论、监管、玩游戏等。

让我们进一步了解其中一个应用场景,将其分解为几个子工作负荷。电子商务网站可以具有很多工作负荷 – 浏览和搜索、结帐和管理、用户注册、用户生成的内容(评论和评分)、个性化等。

假如该应用场景的两个核心工作负荷分别是:

  • 浏览和搜索 - 使客户可以在产品目录中导航,搜索特定商品,还可以管理购物篮或购物单。此工作负荷可以具有一些属性,如匿名用户访问、快速响应时间和缓存。如果响应时间增加,出现意外的用户负载或产品库存清单刷新出现应用程序容忍的中断,则应用程序的性能就可能降级。在这些情况中,应用程序可能选择继续处理缓存中的信息。

  • 结帐和管理 - 帮助客户下订单、跟踪和取消订单,选择交货方式和付款方式以及管理个人资料。此工作负荷也可以具有一些属性,如安全访问、排队的处理、访问第三方支付网关和连接到后端内部系统。尽管应用程序可以容忍响应时间增加,但是却不能容忍订单丢失;因此,它在设计上要确保客户订单始终被接受和捕获,而与应用程序是否可以处理付款或安排交货无关。

应用程序生命周期模型用于定义应用程序在运行时的预期行为。在不同阶段和时间,应用程序会对系统功能或规模级别提出不同要求。生命周期模型将反映这一点。

工作负荷应该以适当的粒度级别为所有相关和适用的应用场景定义了生命周期模型。服务可能在生命周期的不同时间(例如每小时、每天、每周或每个季节)都存在差异,而在对服务建模时需要确定相应的容量、可用性、性能和可扩展性要求。

Failsafe_03

图 1:在不同行业和应用场景中的生命周期示例

通常会有一段时间具有自己独特的生命周期,如:

  • 与假期的峰值需求有关的使用率剧增。

  • 只在截止日期之前填写纳税申报单的量增加。

  • 早晚上下班时间段。

  • 年终填写员工绩效评估。

许多组织都了解这些类型的应用场景以及相关的特定于应用场景的生命周期。

通过拆分,可以在工作负荷级别使用不同内部服务级别协议 (SLA)。这方面的一个示例是体育运动数据 API 示例,其目标 SLA 为 99.99%。但是,你可以将该 API 拆分为两个工作负荷:“现场比分 + 实况报道”和“运动队、队员和联赛统计信息”

对于“现场比分 + 实况报道”工作负荷,生命周期具有“关/开”模式。但是,“运动队、队员和联赛统计信息”的可用性是不变的。通过按工作负荷拆分,你可以使用为复合服务聚合工作负荷的可用性需求定制的 SLA。

Failsafe_12

图 2

确定生命周期模型后,下一步是建立可用性模型和规划。应用程序的可用性模型用于确定你的工作负荷所要求的可用性级别。这很关键,因为它决定了你在构建服务时要做出的很多决策。

你需要考虑诸多事项并可能需要采取一些措施。

制定可用性计划时,了解你的应用程序所要求的可用性级别、应用程序内的工作负荷以及处理这些工作负荷所用的服务是非常重要的。

了解你的工作负荷的生命周期可帮助你选择要达成的 SLA。可能没有为你的服务公开提供 SLA。但是,你的体系结构应将你希望达到的可用性基准线作为目标。

根据你要构建的解决方案的类型,存在许多有关提供更高可用性的注意事项和选项。商业服务提供商不提供 100% 的 SLA,因为提供该级别的 SLA 的复杂性和成本不可行或无利可图。通过将应用程序拆分到工作负荷级别,你可以针对可用性做出决策并实施相关方法。为整个应用程序提供 99.99% 的正常运行时间可能是不可行的,但对于应用程序中的某个工作负荷来说,它是可以实现的。

而且,即使在工作负荷级别,你也不可能选择实施每个选项。你选择实施何种选项,具体取决于你的需求。无论你最终选择哪些选项,都应该是综合考虑了所有选项,深思熟虑后得出的结果。

自治是指构成整体服务的各个组件之间的独立性以及减小它们的相关性。设计服务时必须检查组件、数据和外部实体的相关性,尽力将相关功能构建为服务内的自治单元。这样做可以灵活更新各个自治单元的版本,更好地控制这些自治单元的规模等。

工作负荷体系结构通常包含不依赖人工干预的自治组件,当它们依赖的实体不可用时不会出故障。由自治组件构成的应用程序:

  • 是可用的、运行正常的

  • 有弹性,可以轻松从故障中恢复

  • 出故障的可能性更低

  • 可以通过复制轻松扩展

  • 需要更少的人工干预

这些自治单元通常使用异步通信、基于拉拽的数据处理和自动化过程,以确保服务的连续性。

展望未来,市场上将出现针对垂直和水平应用场景的某类功能的标准化接口。当这一设想成为现实时,服务提供商将可以与不同提供商合作,可能推出适用于自治单元指定工作的不同实现形式。对于连续服务,这将根据策略以自治方式执行。

现在自治还只是个设想,大多数服务仍依赖于第三方服务,即使仅仅是托管。因此必须了解这些从属服务的 SLA 并将它们纳入你的可用性规划中。

本节介绍与你的服务有关的各种不同的 SLA 类型。其中的每种服务类型都有一些需要注意的事项和方法,以及必须弄清楚的问题。

公有云平台服务

商业云计算平台提供的服务(如计算或存储)采用的是适用于大规模用户负载的服务级别协议,而且这些服务的 SLA 是不可协商的。提供商可能提供具有不同 SLA 的服务等级,但是这些等级是不可协商的。服务提供商使用具有不同 SLA 的分层服务级别来提供可预测的服务质量。

以下是此类服务要考虑的问题:

  • 此服务是否只允许对服务 API 发起一定数量的调用?

  • 此服务是否限制调用服务 API 的频率?

  • 此服务是否限制可以调用服务 API 的服务器数目?

  • 服务的可用性承诺提供了哪些公开信息?

  • 此服务如何反映其运行状况?

  • 规定的服务级别协议 (SLA) 包含哪些内容?

  • 还有哪些其他第三方提供等效的平台服务?

第三方“免费”服务

很多第三方向公众提供“免费”服务。对于私营机构,这样做主要是为了帮助围绕其核心产品或服务打造应用程序生态系统。对于公共部门,这样做为了向全体公民和企业提供数据,这些个人和企业已通过纳税向政府提供资金,显然已为数据的收集支付了费用。

大多数这些服务没有服务级别协议,因此不保证其可用性。提供 SLA 时,它们通常侧重于对所使用的应用程序和用于实施它们的机制进行限制。例如,这些限制可能包括在以下条件下限制你的解决方案或将其列入方块列表:当它超过一定数目的服务调用,在给定时间段内超过一定数目的调用(每分钟 x 个),或超过调用服务的允许服务器数时。

以下是此类服务要考虑的问题:

  • 此服务是否只允许对服务 API 发起一定数量的调用?

  • 此服务是否限制调用服务 API 的频率?

  • 此服务是否限制可以调用服务 API 的服务器数目?

  • 服务的可用性承诺提供了哪些公开信息?

  • 此服务如何反映其运行状况?

  • 规定的服务级别协议 (SLA) 包含哪些内容?

  • 它是否是商品服务,所需的功能和/或数据由多个服务提供商提供?

  • 如果是商品服务,它的接口是否可以在其他服务提供商上操作(直接操作或通过可用的抽象层操作)?

  • 还有哪些其他第三方提供等效的平台服务?

第三方商业服务

第三方提供的商业服务具有服务级别协议,这些协议旨在满足付费客户的需求。提供商可以提供具有不同可用性级别的 SLA 等级,但是这些 SLA 是不可协商的。

以下是此类服务要考虑的问题:

  • 此服务是否只允许对服务 API 发起一定数量的调用?

  • 此服务是否限制调用服务 API 的频率?

  • 此服务是否限制可以调用服务 API 的服务器数目?

  • 服务的可用性承诺提供了哪些公开信息?

  • 此服务如何反映其运行状况?

  • 规定的服务级别协议 (SLA) 包含哪些内容?

  • 它是否是商品服务,所需的功能和/或数据由多个服务提供商提供?

  • 如果是商品服务,它的接口是否可以在其他服务提供商上操作(直接操作或通过可用的抽象层操作)?

  • 还有哪些其他第三方提供等效的平台服务?

社区云服务

由多个组织形成的社区(如供应链),可以让服务覆盖成员组织。

以下是此类服务要考虑的问题:

  • 此服务是否只允许对服务 API 发起一定数量的调用?

  • 此服务是否限制调用服务 API 的频率?

  • 此服务是否限制可以调用服务 API 的服务器数目?

  • 服务的可用性承诺提供了哪些公开信息?

  • 此服务如何反映其运行状况?

  • 规定的服务级别协议 (SLA) 包含哪些内容?

  • 作为社区成员,是否可以协商不同的 SLA?

  • 它是否是商品服务,所需的功能和/或数据由多个服务提供商提供?

  • 如果是商品服务,它的接口是否可以在其他服务提供商上操作(直接操作或通过可用的抽象层操作)?

  • 还有哪些其他第三方提供等效的平台服务?

组织内部的企业级云服务

企业可能向自己的内部部门提供核心服务(如股票价格数据或产品元数据)。

以下是此类服务要考虑的问题:

  • 此服务是否只允许对服务 API 发起一定数量的调用?

  • 此服务是否限制调用服务 API 的频率?

  • 此服务是否限制可以调用服务 API 的服务器数目?

  • 服务的可用性承诺提供了哪些公开信息?

  • 此服务如何反映其运行状况?

  • 规定的服务级别协议 (SLA) 包含哪些内容?

  • 作为组织成员,是否可以协商不同的 SLA?

  • 它是否是商品服务,所需的功能和/或数据由多个服务提供商提供?

  • 如果是商品服务,它的接口是否可以在其他服务提供商上操作(直接操作或通过可用的抽象层操作)?

  • 还有哪些其他第三方提供等效的平台服务?

组织内部的部门级云服务

企业部门可能向自己的直属机构的其他成员提供服务。

以下是此类服务要考虑的问题:

  • 此服务是否只允许对服务 API 发起一定数量的调用?

  • 此服务是否限制调用服务 API 的频率?

  • 此服务是否限制可以调用服务 API 的服务器数目?

  • 服务的可用性承诺提供了哪些公开信息?

  • 此服务如何反映其运行状况?

  • 规定的服务级别协议 (SLA) 包含哪些内容?

  • 作为部门的成员,是否可以协商不同的 SLA?

  • 它是否是商品服务,所需的功能和/或数据由多个服务提供商提供?

  • 如果是商品服务,它的接口是否可以在其他服务提供商上操作(直接操作或通过可用的抽象层操作)?

  • 还有哪些其他第三方提供等效的平台服务?

复合服务可用性的“真正的 9 的个数”

利用现有服务可以为你的组织或商业销售灵活提供解决方案。尽管这很有吸引力,但是真正了解这些依赖项对工作负荷总体 SLA 的影响很重要。

可用性通常表示为指定的一年中运行时间的百分比。这样,可用性百分比就可以用“9”的个数来表示。例如,99.9 表示服务的级别为“3 个 9”,99.999 表示服务的级别为“5 个 9”。

 

可用性百分比

每年的停机时间

每月的停机时间

每周的停机时间

90%(“1 个 9”)

36.5 天

72 小时

16.8 小时

95%

18.25 天

36 小时

8.4 小时

97%

10.96 天

21.6 小时

5.04 小时

98%

7.30 天

14.4 小时

3.36 小时

99%(“2 个 9”)

3.65 天

7.20 小时

1.68 小时

99.5%

1.83 天

3.60 小时

50.4 分钟

99.8%

17.52 小时

86.23 分钟

20.16 分钟

99.9%(“3 个 9”)

8.76 小时

43.2 分钟

10.1 分钟

99.95%

4.38 小时

21.56 分钟

5.04 分钟

99.99%(“4 个 9”)

52.56 分钟

4.32 分钟

1.01 分钟

99.999%(“5 个 9”)

5.26 分钟

25.9 秒

6.05 秒

99.9999%(“6 个 9”)

31.5 秒

2.59 秒

0.605 秒

99.99999%(“7 个 9”)

3.15 秒

0.259 秒

0.0605 秒

复合服务提供的“9 的个数”存在一个常见的误解。具体而言,有人认为,如果指定的服务包含 5 个服务,每个服务的 SLA 承诺 99.99% 的运行时间,则最终的复合服务的可用性为 99.99%。这是不正确的。

Failsafe_13

图 3:与常见的“9 的个数”有关的停机时间

复合 SLA 实际上是考虑每年的停机时间综合计算出的值。具有“4 个 9”(99.99%) 的 SLA 的服务脱机时间最多为 52.56 分钟。

将 5 个具有 99.99% SLA 的服务合并为一个复合服务将引入 262.8 分钟或 4.38 小时的 SLA 风险。在编写一行代码前,这会将可用性降低到 99.95%!

通常,确实无法更改第三方服务的可用性。但是,如果编写代码,你可以使用本文档中所述的那些技术增加应用程序的整体可用性。

note备注
某些服务可能会为不同价位或基于商业合作伙伴关系提供不同层的服务。

请考虑我们先前引用的体育运动数据 API。用户只在某些天并且只在这些天的特定几个小时内打比赛。在这些时段内,SLA 将为 100%。当没有安排比赛时,此工作负荷使用 0% 的 SLA。“运动队、队员和联赛统计信息”工作负荷具有更一致的生命周期模式。另外,还要求该工作负荷一直始终使用 99% 的 SLA。

Failsafe_14

图 4

利用外部服务时,了解 SLA(无论是对单个服务还是它们对复合服务的影响)的重要性不言而喻。

要创建弹性体系结构,了解该结构很重要。具体而言,即主动了解和记录可能导致停机的因素。

了解应用程序及其相关工作负荷服务的故障点和故障模式,可以帮助你制定出明智、有针对性的弹性和可用性策略。

故障点是故障可能会导致服务中断的位置。我们将重点放在受外部更改影响的设计元素上。

故障点的示例包括:

  • 数据库连接

  • 网站连接

  • 配置文件

  • 注册表项

常见故障点的类别包括:

  • ACL

  • 数据库访问

  • 外部网站/服务访问

  • 事务

  • 配置

  • Capacity

  • 网络

故障点定义可能导致停机的区域,故障模式则标识故障可能出现的具体方式。

故障模式的示例包括:

  • 配置文件缺失

  • 流量大大超过资源容量

  • 数据库达到最大容量

故障影响是故障在功能上造成的后果。了解有关故障影响以及可能发生这些类型的故障的频率的信息。通过这样做,你可以优先考虑何时以及如何处理应用程序或服务的故障点和故障模式。

本文档将介绍与计算、存储和平台服务有关的重要注意事项。在介绍这些主题前,有必要简单概述一下通常被误解和/或未实现的几个基本弹性影响主题。

如前文所述,弹性体系结构应进行优化以实现组件的自治。实现自治的方式之一是采用异步通信。弹性体系结构应默认为异步交互,同步交互仅当出现异常时才发生。

无状态的 Web 层或具有分布式缓存的 Web 层可以在解决方案的前端提供此功能。队列可以为工作负载服务之间的交互或一个工作负载服务内的各服务之间的交互提供异步通信功能。

后者允许将消息放置到队列并且辅助服务可以检索这些消息。这可以基于逻辑、时间或容量考虑的逻辑来实现。除了让该过程采用异步方式之外,它还允许在队列中以“推送”或“拉拽”的方式将层缩放为合适的规模。

经常发生暂时性故障的区域是体系结构连接到服务或资源(如数据库)的地方。使用这些服务时,通常需要实现引入超时概念的逻辑。此逻辑会设置一个时间范围,并认为在这个时间范围内收到响应是可接受的,并且在超过该时间范围时生成一个可识别的错误。出现超时错误后,需要根据发生错误的上下文采取相应的措施。上下文可能包括此错误出现的次数、不可用资源的潜在影响,以及当前时间段的 SLA 承诺是否符合指定客户的要求等。

设计将要处理你的工作负荷的服务时,你必须接受和容忍这些故障的发生,并采取相应措施解决它们。

要解决的一个常见故障就是暂时性故障。因为任何服务都不可能保证 100% 的运行时间,因此只能尽可能做到减少工作负荷与所连接的服务之间的依赖程度。无法连接到其中的某个服务或者服务出现故障,这种情况可能是暂时的(持续不到一秒),也可能是永久的(提供商关闭服务)。

适当降级

你的工作负荷服务应该能够以合理方式处理这些暂时性故障。例如,在因为云提供商停机而导致主数据存储区不可用时,Netflix 会为客户提供较旧的视频队列。又例如,电子商务网站在支付网关不可用时仍然能够继续收集订单。这样,在支付网关恢复正常工作或故障转移到辅助支付网关后,电子商务网站可以立即处理订单。

可接受降级的高级别注意事项

在考虑如何以可接受的方式降级时,需要注意以下重要事项:

  • 没有请求的完整上下文的组件应该只是失败并传递异常消息。若要解决此问题,请实施断路器(在本文档的后面部分描述),以便在达到失败计数阈值时快速失败。

  • 本质上可能是暂时性的失败是常见的。请使用本文档后面部分所述的重试模式来处理这些失败。

  • 调用方可能能够通过使用不同参数或不同路径重试请求来更正一些失败的请求。

  • 如果请求是否成功对于方案并非至关重要,请通过简单的排除来处理失败。

  • 你可以通过返回成功消息来处理失败,并将失败的请求排队,等到以后资源恢复到正常状态时再处理。

  • 你可能能够从缓存中返回一些以前正确的内容,例如,缓存的凭据、过时的数据等。

  • 你可以通过提供一种接近正确的体验(例如,临时访问、近似值、最佳猜测,noscript 等)来处理一些失败。

  • 不是引发错误,你可能能够提供一些替代内容,例如,随机值、匿名权限、默认图像等。

暂时性故障处理注意事项

在以下章节中,我们将详细介绍实现暂时性故障处理的几个重要注意事项。

  • 重试逻辑

    暂时性故障处理的最简单方式是重试失败的操作。如果使用的是第三方商业服务,实现“重试逻辑”通常将解决此问题。

    请注意,设计通常应限制逻辑重试的次数。逻辑通常尝试执行一定次数的操作,如果故障仍存在,将记录错误和/或使用辅助服务或工作流。

  • 指数退让

    如果暂时性故障是由于负载过重而导致服务对操作采取了限制措施,那么重复尝试调用服务只会延长限制措施的时间,并最终影响总体可用性。

    在这种情况下,通常需要减少对服务的调用,帮助避免或减少限制情形的发生。这一般通过算法来实现,例如在第一次失败后立即重试,在第二次失败后等待 1 秒后重试,在第三次失败后等待 5 秒后重试等等,直到最后成功或达到应用程序定义的失败次数阈值。

    此方法称为“指数退让”。

  • 幂等性

    对于所连接的服务而言,一个核心假设是这些服务不可能是 100% 可用,并且使用重试逻辑处理暂时性故障是核心的实现手段。在实现重试逻辑的情况下,可能会出现同一消息发送多次,以及消息乱序发送等情形。

    操作应设计为具有幂等性,确保多次发送同一条消息不会导致数据存储区出现意外或受到污染。

    例如,如果服务操作被调用了多次,那么所有请求中的插入数据操作可能导致添加多条记录。一种解决方法是在代码中实现智能“插入更新”(upsert)。插入更新的工作原理是:使用时间戳或全局标识符将新的消息从以前处理过的消息中区分出来,如果新消息中包含的记录在数据库中不存在,则将该记录插入数据库中;如果新消息中包含的记录在数据库中已经存在并且要比以前消息中的记录更新,则更新数据库中的现有记录。

  • 补偿行为

    除了幂等性之外,另一个要考虑的领域是补偿行为的概念。随着所连接的系统不断增长和组合服务不断涌现,了解如何处理补偿行为也变得越来越重要。

    对于许多业务线应用程序开发人员而言,事务的概念并不陌生,但参考框架通常与由本地数据技术公开的事务功能和相关代码库密切相关。当从云的角度考察此概念时,这一理念需要考虑与分布式服务的业务流程相关的新内容。

    服务业务流程可以跨多个分布式系统,且长期运行并具有状态。业务流程本身极少是同步的,它可以跨多个系统,且时间跨度根据业务方案可从几秒到几年。

    一个供应链方案在同一个工作负荷活动中可能会涉及 25 个组织,因此可能会有 25 个或更多系统在一个或多个服务业务流程中相互连接。

    如果某个活动成功执行,就必须让这 25 个系统都知道。对于活动中的每个连接点,参与的系统可能会为它从其他系统收到的消息提供一个相关 ID。根据活动的类型,如果某个系统收到了相关 ID,该系统就可能会认为事务已经完成。在其他情况下,当完成所有 25 个系统的交互后,可能会向所有系统发送确认消息(要么直接从单个服务发送,要么通过每个系统的特定业务流程交互点发送)。

    为了处理组合活动和/或分布式活动中的故障,每个服务都会公开一个服务接口以及一个或多个操作,以便接收请求来根据唯一标识符取消给定的事务。在服务后方,可能需要设置工作流来补偿因取消此活动所带来的影响。在理想情况下,这些过程都是自动执行的,但也可以采用更为简单的方式,将这些过程路由到组织内的某个人来手动进行补救。

断路器原意是指一种电路开关,当电流超过预设的限制时,断路器将自动中断电流。断路器最常用的功能是作为一种安全防范措施,以防止通过电路的电流太大而可能带来危险。与保险丝不同,断路器可以重置和重复使用。

同样的模式也适用于软件设计,尤其适用于对可用性和灵活性要求很高的服务。

在资源不可用的情况下,实现软件断路器可以正确地响应请求,并执行正确的操作。

断路器将会有三种状态:“已关闭”、“打开”和“半开”。

“已关闭”状态是应用程序或服务的正常状态。当处于“已关闭”状态时,请求通过标准路径进行路由。计数器将记录故障率,并根据阈值对其进行评估。如果该故障率超出阈值,断路器将更改为“打开”状态。如果在 100 次连续尝试连接后调用数据库资源失败,则继续调用此数据库可能没有什么价值。在达到该阈值时,可以触发断路器,并且采取相应的措施。

当处于“打开”状态时,断路器将请求路由到缓解路径。这可能导致快速失败或某种其他形式的可接受降级。当切换到“打开”状态时,断路器还将启动计时器。当计时器到期时,断路器将切换到“半开”状态。

“半开”状态将开始通过正常路径路由数目有限的请求。如果这些请求成功,断路器将切换到“已关闭”状态。如果这种有限数目的请求失败,则断路器将返回到“打开”状态。

在你的体系结构中包含断路器模式时,请考虑以下事项:

  • 当处于“打开”状态时,断路器可以根据从操作引发的异常类型,调用不同的缓解措施或调用不同次数。

  • 断路器应记录所有转换状态。这使操作员可以监视转换行为,并微调计时器以防止长期处于“打开”状态或在“打开”和“半开”状态之间频繁振荡。

  • 断路器不是使用计时器来从“打开”转换到“半开”,而是可以定期测试标准路径,以确定它是否已再次变为正常状态。

  • 在处理会导致多个分片的操作时,使用断路器要小心。这里需要关注的是运行状况可能在分片级别判定,从而可能导致两种不希望发生的情况:

    • 当只有一个分片发生故障时,就转到“打开”状态。

    • 当一个或多个分片正常时,意外转到“已关闭”状态。

此模式的一种常见实现与访问数据库或数据服务相关。一旦已建立的活动类型和级别失败,断路器就会作出反应。对于数据而言,这通常是由于无法连接到数据库或位于该数据库前面的数据服务而导致的。

如果连续调用数据库资源 100 次都失败,则继续调用此数据库可能没有什么价值。在达到该阈值时,可以触发断路器,并且采取相应的措施。

在某些情况下,尤其当连接到数据服务时,这可能是因为客户端超出了给定时段内允许的调用次数而被施加了限制。断路器可能会在调用之间注入延迟,直到连接成功建立并满足容错级别。

在其他情况下,数据存储区可能不可用。如果提供了数据的冗余副本,则系统可以故障转移到该副本。如果不能提供真正的副本,或提供商的所有数据中心都发生大范围数据库服务停机事件,则需要采取辅助手段。这些手段包括从备用数据服务提供商那里请求某个版本的数据。这种备用数据源可能来自缓存、当前云提供商的备用持久数据存储区类型、单独的云提供商或内部数据中心。当此类备用数据源也不可用时,服务还可能返回能够让客户端正确处理的可识别错误。

断路器示例:Netflix

Netflix 是一家流媒体提供商,常被当作弹性体系结构的榜样。当讨论 Netflix 的断路器模式时,该团队会强调其断路器中包括的若干准则,具体内容请参阅 Netflix 技术博客。这些准则包括:

  1. 对远程服务的请求超时。

  2. 用于与服务依赖项交互的线程池和绑定的任务队列用掉了 100% 的容量。

  3. 用于与服务依赖项交互的客户端库引发一个异常。

所有这些都计入总体错误率。当错误率超出定义的阈值时,断路器将“跳闸”,该服务的“电路”将立即提供回退机制,甚至不会尝试连接远程服务。

在这同一篇博客文章中,Netflix 团队表示,其每项服务的断路器都会使用以下三种手段之一实现回退机制:

  1. 自定义回退:服务客户端库提供一个可调用的回退方法,或者使用 API 服务器上本地提供的数据(如 cookie 或本地缓存)来生成回退响应。

  2. 无提示失败:一个方法向发出请求的客户端返回 Null 值,当所请求的数据属于可选数据时,这种手段的效果很好。

  3. 快速失败:当数据是必需的或没有好的回退机制时,将向客户端返回 5xx 响应。这种方法侧重于使 API 服务器保持正常运行状态,并在受影响的服务返回联机状态时能够快速恢复,但代价是对客户端 UX 产生负面影响。

为了确保达到 SLA,组织应解决其数据服务应如何处理两类离群值:可信方和不良参与方。

可信方和允许列表

可信方是指对数据服务提供商有特殊意义的一些组织,针对这些组织可能采用一些非标准的 SLA。

  • 具有自定义协议的第三方

    服务的某些用户可能希望协商特殊的价格条款或政策。在某些情况下,需要大量调用数据服务的组织可能要求获得特殊价格。在其他情况下,某些组织对于给定数据服务的需求可能会超出标准使用协议中规定的量。此类客户应定义为可信方,以避免无意中将它们标记为不良参与方。

  • 允许列表

    处理可信方的典型方法是建立允许列表。允许列表是用于标识可信方的列表,服务使用此列表来确定在处理客户使用情况时所应用的业务规则。允许列表通常是通过对 IP 地址范围或 API 密钥进行授权来实现的。

    当建立使用策略时,组织应确定是否支持允许列表;客户应如何申请列入允许列表;如何将客户添加到允许列表;以及在什么情况下从允许列表中删除客户。

  • 处理不良参与方

    既然客户群中有可信方,自然也就有对立的一面“不良参与方”。不良参与方对服务施加了负担,通常是试图“过度使用”。在某些情况下,不良行为实际上是意外导致的。在其他情况下,不良行为是故意的;而在少数情况下,这种行为甚至是恶意的。这些参与方之所以被标记为“不良”,原因是其操作(无论是有意还是其他)能够影响一项或多项服务的可用性。

    不良参与方所带来的负担可能会给数据服务提供商带来不必要的成本,并且会妨碍那些忠实遵守使用条款并且理应享受合理服务(在 SLA 中规定)的客户访问相关的服务。因此,必须采用规定的、一致的方式处理不良参与方。对于不良参与方的典型处理方式是限制和列入方块列表。

  • 限制

    组织应制定策略来处理数据服务使用方的使用高峰。来自任何使用方的大量突发流量都可能给数据服务带来意外负载。当发生此类高峰负载时,组织可能希望限制该使用方在特定时段内对服务的访问。在这种情况下,服务将在给定时段(如一分钟、五分钟或十分钟)内拒绝来自该使用方的所有请求。在此期间,来自目标使用方的服务请求将导致显示错误消息,指出他们因为过度使用而受到限制。

    发出请求的使用方可以采取相应的措施,例如改正自己的行为。

    组织应确定自己是否要实施限制以及是否要设置相关的业务规则。如果组织确定可以对使用方进行限制,还需要决定什么行为应触发限制响应。

  • 方块列表

    尽管通过限制应该能够纠正不良参与者的行为,但这种方法并不总是能够取得成效。如果这种方法不奏效,组织可能需要禁止使用方。与允许列表相反的是方块列表,方块列表用于标识被禁止访问服务的使用方。对于来自方块列表中的客户发出的访问请求,服务可以最大限度地限制他们对数据服务资源的使用。

    方块列表与允许列表一样,通常是使用 API 密钥或 IP 地址范围来实现。

    当建立使用策略时,组织应指定什么行为会导致客户被列入方块列表;如何对方块列表进行申诉;以及如何从方块列表中移除客户。

人非圣贤,孰能无过。开发人员可能搞错代码导致产生意外结果,数据库管理员可能意外删除数据库中的表,操作员可能进行了更改但没有记录下来,人总是可能因为各种各样的因素造成服务的弹性意外下降。

为了减少人为错误,可以通过逻辑手段来减少此过程中的人员参与。通过引入自动执行机制,你可以限制因人为因素导致临时、意外差错而危害服务的可能性。

DevOps 社区中有一个宣传画,画中的卡通人物说道,“让所有过程都自动执行”。在云中,大多数服务都是通过 API 公开的。从开发工具到虚拟化基础结构、平台服务以及以“软件即服务”形式交付的解决方案,大多数内容都是可以通过脚本来实现的。

强烈建议使用脚本。脚本使部署和管理能够保持一致且可预测,且投资回报率相当高。

自动执行部署

自动执行机制的一个关键领域是在构建和部署解决方案的过程中。通过自动执行机制,开发人员团队可以轻松地测试并部署到多个环境。通过自动化的过程,可以轻松和一致地部署开发、测试、临时、二次测试和生产等所有阶段。跨环境且一致地进行部署的能力旨在确保生产阶段的内容是测试内容的典型代表。

请将以下内容视为“代码”:与部署相关的脚本、配置文件和元数据。代码还包括管理源控件中的这些项目,以便:

  • 记录更改。

  • 允许版本控制。

  • 提供基于角色的访问控制。

  • 确保内容已备份。

  • 提供单一可信源。

建立并自动执行测试流程

测试是另一个可以实现自动化的领域。与自动执行的部署类似,建立自动执行的测试也极为重要,可确保系统具有弹性且随着时间推移仍能保持弹性。随着服务的代码和使用情况不断发展变化,有关功能和规模方面的所有适当的测试仍有必要继续执行,这一点很重要。

自动执行数据存档和清除

还有一个不太引起关注的领域,那就是数据存档和清除。数据量一直在增长,数据量和数据种类已经增长到比历史上任何时候都更高和更多。根据数据库技术和需要的查询类型,多余数据可能会延长系统的响应时间,进而增加不必要的成本。对于包含数据存储区的一个或多个副本的弹性规划而言,删除必需数据之外的所有内容可以加快管理活动(如备份和还原数据)的速度。

确定你的解决方案在以下各个方面的要求:核心功能所需的数据、合规性所需但可以存档的数据,以及不再需要而可以清除的数据。

利用相关产品和服务中提供的 API 可以自动实现这些要求。

当构建弹性体系结构时,还务必理解故障域和升级域概念。

故障域

故障域根据已知的硬件边界和可能受某一特定中断类型影响的一组计算机来划分并且约束服务的位置。故障域定义为一系列可能同时出现故障的计算机,且通常按物理属性定义(特定的机架、一系列共享同一电源的计算机等等)。

升级域

升级域与故障域类似。升级域是指系统在同一时间进行更新的一系列实际服务。云提供商的负载平衡器必须知道这些升级域,才能确保在更新特定的域时,整体系统保持平衡且服务保持可用。

升级可以发生在:

  • 虚拟机监控程序级别(“HostOS 升级”)。

  • 操作系统级别(“来宾 OS 升级”)。

  • 作为将应用程序或服务升级部署到环境中的结果。

根据所使用的云提供商和平台服务,故障域和升级域可能是自动提供的,也有可能是你的服务需要通过 API 才能加入,或者是需要采用第一方或第三方解决方案才能实现。

在升级过程中容错域出现故障期间的复原能力

虽然容错域和升级域不同,但它们存在相交的应用场景。在该应用场景中,硬件故障使虚拟机脱机,而升级同时在另一个 VM 实例上进行。在这种情况下,这两个 VM 都会脱机。如果服务部署只包含这两个虚拟机,则该服务将脱机。在评估提供你想要的 SLA 所需的实例数时,请考虑到这种情况。

云平台通常提供为一组资源确定关联级别的功能。我们将这些资源称为“地缘组”或“地缘集”。这可帮助基础平台将相关资源放置在一起,并将实例分配到容错域和升级域。

内部解决方案通常依赖于冗余来帮助它们实现可用性和可扩展性。从可用性观点来看,通过冗余的数据中心,可以在给定数据中心或数据中心的组成部分出现基础结构故障时提高业务持续的可能性。

对于用户分布在世界各地的应用程序而言,流量管理和冗余实现会将用户路由到本地资源,这通常会减少延迟。

note备注
数据弹性(包括冗余)将在本节的“建立数据弹性方法”主题中单独介绍。

冗余和云

对于内部解决方案而言,冗余一直是通过一系列重复的硬件、软件和网络来实现的。有时,这是通过在单一位置在一个群集中实现的,也可以分布在多个数据中心。

当设计云策略时,必须围绕三个因素来合理定夺冗余的需要。这些因素包括云提供商的环境中的已部署代码、提供商自身的冗余以及云与内部之间的冗余。

部署冗余

当组织选择了云提供商之后,必须针对该提供商内的部署建立冗余策略。

如果部署为“平台即服务”(PaaS),则其中的许多工作可以交由基础平台来处理。而在“基础结构即服务”(IaaS) 模型中,许多工作并不由基础平台来处理。

  • 在数据中心内部署一系列角色

    最简单的冗余形式是将你的解决方案部署到单个云提供商中的多个实例上。通过部署到多个实例,解决方案的可用性要比部署在单个节点上更高。

    在许多“平台即服务”环境中,托管代码的虚拟机的状态处于监控之下,如果检测到某个虚拟机的运行状况不正常,则会自动替换为正常运行的节点。

  • 跨多个数据中心部署

    尽管在单个数据中心内部署多个节点具有一定的优势,但体系结构必须考虑到整个数据中心也有可能不可用。尽管这种情况并不常见,但诸如自然灾害、战争等事件可能导致服务在某个特定地理位置中断。

    为了符合 SLA 的要求,你可能有必要将你的解决方案部署到所选云提供商的多个数据中心。实现此部署的方法有很多,具体如下。

    1. 多个数据中心内完全冗余的部署

      第一个选项是在多个数据中心实现完全冗余的解决方案,并结合使用流量管理提供程序。对于这种冗余类型,需要重点考虑与计算相关的成本:每增加一个冗余数据中心部署,此成本都会增加 100%。

    2. 在辅助数据中心实现部分部署以进行故障转移

      另一种方法是在辅助数据中心部署一部分解决方案,这样可以减小部署的大小。例如,如果标准配置需要部署 12 个计算实例,则辅助数据中心可以只部署 6 个计算实例。

      将这种方法与流量管理相结合,如果主数据中心发生意外,你的业务仍然可以继续运行,只不过服务会降级。

      考虑到数据中心整体进入脱机状态的次数少之又少,上述方法通常被视为一种经济高效的计算方法,尤其在平台允许组织轻松地加载辅助数据中心内的新实例的情况下。

    3. 将部署划分到多个具有备份节点的数据中心

      对于某些工作负荷,尤其是金融服务领域的工作负荷,必须在很短且固定的时间窗口内处理大量数据。在这些情况下,要完成的工作量在短期内暴增,应确保冗余成本以便能够在该时间窗口内交付结果。

      对于此类情况,应将代码部署到多个数据中心。工作量经过拆分后分布在多个节点间进行处理。在某个数据中心不可用的情况下,原本由该节点处理的工作量将转至备份节点,由备份节点来完成任务。

    4. 部署到多个数据中心,而每个数据中心根据地理位置适当进行规模调整

      这种方法在多个数据中心内存在冗余部署,但这些冗余部署的大小则根据该地理位置的用户规模进行了适当调整。

提供商冗余

尽管以数据中心为中心的冗余很不错,但 SLA 是以服务级别而非数据中心级别作为基准的。现在许多商业服务都将新版本部署到生产“切片”,以便在生产中对代码进行验证。但是,存在这样的可能性:提供商所提供的服务可能会在多个或所有数据中心都不可用。

因此,根据解决方案的 SLA,可能还需要结合使用提供商冗余。要实现此目标,必须确定你要部署到云的产品或云服务可以在多个云平台上工作。例如 Microsoft SQL Server,就可以部署到大多数供应商提供的“基础结构即服务”产品内的虚拟机中。

对于云提供的服务,这种做法更具有挑战性,因为没有现成的标准接口,甚至对诸如计算、存储、队列等此类核心服务也是如此。如果这些服务需要提供商冗余,则通常只能通过抽象层来实现。抽象层可以为解决方案提供足够的功能,但它的创新速度比不上基础服务,可能使组织无法轻松地采用提供商交付的新功能。

如果冗余提供商服务得到保证,则可能处于以下几个级别之一:整个应用程序、工作负荷或工作负荷的一个方面。在适当的级别,评估计算、数据和平台服务的需要,并确定哪些内容切实需要冗余以及哪些内容可以通过某些方法来提供可接受的降级。

内部冗余

尽管依赖于云提供商可能能够获得财务上的优势,但一些业务因素可能要求实现内部冗余,以满足合规性和/或业务连续性要求。

根据解决方案的 SLA,可能还需要结合使用内部冗余。要实现此目标,必须确定你要部署到私有云的产品或云服务可以在多种云类型中工作。在提供商冗余部分提及的 Microsoft SQL Server,同样也是一个可在内部或 IaaS 产品中部署的产品的良好范例。

对于云提供的服务,这种方法也颇具挑战性,因为某些接口和功能也没有内部对应项。

如果内部需要冗余提供商服务,则这可能处于以下几个级别之一:整个应用程序、工作负荷或工作负荷的一个方面。在适当的级别,评估计算、数据和平台服务的需要,并确定哪些内容切实需要冗余以及哪些内容可以通过某些方法来提供可接受的降级。

冗余配置方法

当确定你的冗余配置方法时,实现云之前存在的分类也适用。根据你的解决方案中利用的服务类型,其中某些功能可由基础平台自动处理。在其他情况下,这一功能通过诸如 Windows Fabric 之类的技术来处理。

  1. 主动/主动:原本由故障节点处理的流量要么传递到现有节点,要么在剩余节点上实现负载平衡。这种情况通常只在这些节点使用同类软件配置时才可能实现。

  2. 主动/被动:提供每个节点的完全冗余实例,此实例仅当其关联的主节点出现故障时才进入联机状态。这种配置通常需要最多的额外硬件。

  3. N+1:提供单个额外节点,该节点进入联机状态以接管故障节点的角色。如果每个主节点都采用异构软件配置,此额外节点必须普遍能够承担它所负责的主节点的任何角色。这通常指同时有多个服务正在运行的群集;在单个服务的情况下,这会退化到主动/被动模式。

  4. N+M:在单个群集管理许多服务的情况下,只有一个专用故障转移节点可能无法提供足够的冗余。在此类情况下,应该包括多个 (M) 备用服务器且这些服务器都可用。备用服务器的数量是综合考虑成本与可靠性要求之后得出的数字。

  5. N 对 1:允许故障转移备用节点临时成为活动的节点,直到原始节点可以还原或恢复在线状态,此时,服务或实例必须故障转移回原始节点,以还原高可用性。

  6. N 对 N:主动/主动和 N+M 的组合,N 对 N 在剩余活动节点间重新分配故障节点中的服务、实例或连接,这样就不再需要“备用”节点(对应于主动/主动),但要求所有活动节点上具有额外的容量。

无论流量是在地理上分散的,还是传送到不同数据中心以满足业务连续性方案的要求,流量管理功能都是至关重要的,可确保对解决方案的请求被传送到适当的实例。

务必注意,依赖于流量管理服务会引入单一故障点。应该调查应用程序的主要流量管理服务的 SLA,并确定备用流量管理功能是否可以保证符合你的要求。

尽管许多可扩展性高的云应用程序对其 Web 层进行了很好的分区,但它们在云中扩展数据层则鲜有成功。随着所连接的设备越来越多样化,所生成和查询的数据的级别正在史无前例地增长。例如,每天可支持 500,000 个新用户的需要现在已是合理要求。

跨多个维度(包括存储、查询或维护这些数据)实施分区策略极其重要。

分解和分区

由于不同技术都具有各自不同的优缺点,因此常用的方法是针对给定的工作负荷采用最合适的技术。

如果你的解决方案已经根据工作负荷进行了分解,你可以选择最适合给定工作负荷的数据技术。例如,某个网站可能利用表存储来存储某个人的内容,同时在用户级别利用分区来获得响应体验。这些表行可能定期聚合到一个关系数据库中以进行报告和分析。

分区策略可能而且也通常会因为所选择的技术而有所差异。

定义策略时,确定可能需要已修改策略或并行策略的离群值也很重要。例如,如果你正在开发一个社交站点,一个普通用户可能需要 500 个连接,而一位名人可能需要 5,000,000 个连接。

如果该站点预计 1 亿用户,其中名人少于 50,000 个,则会针对典型用户优化核心分区策略。你将会以不同方式管理名人。虽然你会将大量用户分组在单个分区中,但你可能会将名人分配到他自己的分区。

了解 3V

要正确地设计分区策略,组织必须首先了解分区策略。

3V 在 Gartner 的推动下已变得广受欢迎,它考察数据的三个不同方面。了解与你的数据相关的 3V,可帮助你制定出明智的分区策略决策。

  • 数据量(Volume)

    数据量指数据的大小。数据量对于分区策略具有非常实际的影响。特定数据技术的数据量限制可能会由于大小限制、大量数据的查询速度等因素而强制进行分区。

  • 速度 (Velocity)

    速度指数据的增长速率。对于增速较慢的数据存储区与需要每天容纳 500,000 位新用户的数据存储区,你可能需要分别设计不同的分区策略。

  • 种类 (Variety)

    种类指的是与工作负荷相关的不同类型的数据。无论它是关系数据、键值对、社交媒体个人资料、图像、音频文件、视频或其他类型的数据,都务必了解它们。这同时关系到选择正确的数据技术以及针对分区策略做出明智的决策。

水平分区

对数据进行分区的最常用方法很可能就是对数据进行水平分区。当执行水平分区时,需要确定相关的条件,以便将数据存储区划分为多个分片。每个分片都包含一个完整的架构,而这些条件决定将数据放入适当的分片中。

根据数据类型和数据使用情况,这可以通过不同方法实现。例如,组织可以选择根据客户的姓氏对数据进行分区。或者,也可以围绕着日期,按照相关的日历间隔(小时、天、周或月)来进行分区。

水平分区关系图

图 5:按姓氏进行水平分区的示例

垂直分区

另一种方法是垂直分区。这种方法可以优化数据在不同存储区中的放置情况,这通常与数据的种类密切相关。图 5 显示了一个示例,其中有关客户的元数据放在一个存储区中,而缩略图和照片放入单独的存储区中。

垂直分区可以优化数据的存储和交付。例如,在图 5 中,如果客户的照片极少显示,则每个记录返回 3 MB 可能会增加不必要的成本。

垂直分区关系图

图 6:垂直分区的示例

混合分区

在许多情况下,建立混合分区策略非常适合。这种方法在单个解决方案中结合了上述两种方法的优点。

图 6 显示了混合分区策的一个示例:前面介绍的垂直分区现已得到了增强,以充分利用客户元数据的水平分区。

水平分区关系图

图 7:混合分区的示例

云计算的核心是网络。网络非常重要,因为它是设备连接到服务以及服务连接到其他服务的基石或支柱。在任何“防故障”(FailSafe) 应用程序中,都要考虑三个网络边界。

下面将以 Azure 环境为例详细介绍这些网络边界:

  1. 角色边界传统上称为层。常见的示例为 Web 层或业务逻辑层。如果我们以 Azure 为例,它正式引入角色作为其核心设计的一部分,为最新的分布式应用程序的多层特性提供了基础结构支持。Azure 可保证属于同一服务的角色实例托管在单个网络环境的范围内,并由单个结构控制器进行管理。

  2. 服务边界表示对其他服务所提供的功能的依赖性。针对关系数据库访问的 SQL 环境以及针对发布/订阅消息传递支持的 Service Bus 就是服务边界的常见例子。例如,在 Azure 内,服务边界是通过网络来强制划定的:服务依赖项并不一定是相同网络或结构控制器环境的一部分。这种情形可能会发生,但对于任何负责任的应用程序来说,都必须执行这样的设计:任何服务依赖项都应该处于不同结构控制器管理的不同网络上。

    云服务角色实例关系图
    图 8

  3. 端点边界位于云的外部。它们包括任何 连接到云以便使用服务的使用端点,通常假定为设备。你必须在这方面的设计上加以特别考虑,因为网络的本质就是充满变数且不可靠。角色边界和服务边界位于云环境的边界内,并且可以假设具有某个级别的稳定性和带宽。对于外部依赖项,则无法做出这样的假设,并且必须对设备使用服务的能力(即数据和交互)予以特别关注。

    由于网络的特性,在将信息从一个网络点传递到其他网络点时会产生延迟。为了向用户以及相关服务或角色提供极佳的体验,应用程序体系结构和设计应该寻找尽可能减少延迟的方法,并且以明确的方式管理无法避免的延迟。减少延迟最常见的一种方法是避免发生与网络有关的服务调用 -- 以本地方式访问数据和服务是减少延迟和加快响应速度的最佳方法。使用本地数据和服务还提供另一层级的失败保护;一旦用户或应用程序发起的请求可以在本地环境中解决,就无需与其他角色或服务交互,从而消除了由于相关组件不可用而引发故障的可能性。

缓存

缓存是一种当无法在本地存储数据时用来提高数据访问速度的技术。在当今运营规模较大的大多数云服务中,都利用缓存取得了极佳效果。根据 Wikipedia 摘要提供的定义,缓存将应用程序反复请求的数据存储在本地,从而加快访问速度。缓存依赖于以下两个方面:

  • 用户以及相关应用程序的数据使用模式以只读为主。在某些情形下,例如电子商务网站,在用户与网站的所有交互中,只读访问(有时候称作浏览)所占的比例高达 95%。

  • 应用程序的信息模型提供额外的一个语义信息层,支持标识稳定单一的信息,而此类信息最适合使用缓存。

设备缓存

尽管设备缓存不是防故障 (FailSafe) 倡议关注的重点,但这种方法确实是一种可用来增加任何设备和服务应用程序的可用性和可靠性的有效方法。现在有很多方法可在设备或客户端层上提供缓存服务,包括可以在所有标准浏览器中实现本机缓存功能的 HTML5 规范,以及 SQL Server Compact Edition 之类的本地数据库实例等等。

分布式缓存

分布式缓存包括一系列强大的功能,但它并不是要取代关系数据库或其他持久存储区;它的目的是提高分布式应用程序的响应性,而响应性实质上是以网络为中心,因此对延迟十分敏感。引入缓存的一个连带好处是减少了持久数据存储区的流量,从而最大限度降低了与你的数据服务的交互。

  • 针对缓存优化的信息模型

    note备注
    本部分中的许多内容都基于 Pat Helland 在探讨数据在面向服务的体系结构世界中的作用时所做的杰出贡献。你可以在 Microsoft 开发人员网络中阅读整篇文章

    缓存的数据本质上是陈旧的数据,也就是说,不一定最新的数据。缓存的数据就像是发送给数以千计家庭的产品目录,尽管这个例子取自完全不同的领域,但是却非常贴切。在创建该目录时,生成产品目录的数据是最新的。在将目录印刷过程中,因为时间的关系,数据会变得陈旧。由于缓存的数据是陈旧的数据,因此数据在稳定性和单一性方面的属性对于缓存设计而言至关重要:

    • 稳定性 - 在空间和时间上具有明确解释的数据。这通常意味着数据值不会发生更改。例如,大多数企业永远不会重复利用客户标识或 SKU 号码。创建稳定数据的另一个技术是向现有数据添加到期日期。上面的印刷产品目录就是一个很好的例子。通常,零售商会在两个发布期间内接受来自任何给定目录的订单。如果一年发布四次目录,则产品目录数据在 6 个月内是稳定的,并且可用于下订单和履行订单之类的信息处理。

      稳定数据通常称作主数据或“引用数据”。在防故障 (FailSafe) 倡议中,我们将采用“引用数据”一词,因为从语义上来讲,它要比主数据的适用范围更广。在许多企业中,主数据具有非常特定的意义,使用范围比引用数据要窄。

    • 单一性 - 能够与可唯一标识的实例加以关联从而隔离出来,而且不发生并发更新或并发更新频率很低的数据。以购物篮为例。尽管购物篮很明显是可以更新的,但更新相对来说并不会频繁发生,而且从存储以及处理角度来说可以完全隔离。

      上述可隔离的数据一般称之为“活动”数据或会话数据。

      在记住这两个属性之后,以下架构将就形成:

      数据类型关系图
      图 9

  • 信息模型

    许多应用程序架构师或开发人员在考虑信息模型时都会考虑对象模型或实体模型。尽管对象模型或实体模型是信息建模不可或缺的一部分,但对于防故障 (FailSafe) 应用程序来说,信息模型的构成中还有许多其他元素。

    在如今的分布式世界中,需要考虑的首要对象就是稳定性和单一性。另一个关键元素是理解在与用户/设备交互时或者作为要实现的业务流程的一部分时如何利用数据。面向对象的模型应该是以多种方式成为信息设计的一部分:

    • 信息隐藏 - 隐藏对用户或业务流程没有用处的信息或者不提供对此类信息的访问,是避免与在关系数据库中存储和管理的资源或共享数据发生冲突的最佳方式之一。

      为了更好地了解如何利用信息隐藏来大幅改进并发性,我们来分析一下典型的 ERP 系统与 Amazon.com 管理库存的方法之间的差异。在典型的 ERP 系统实现中,库存表是最拥挤或最常用的表之一(如果假定采用关系数据库)。ERP 应用程序通常会在用户完成交易之前尝试锁定库存,并且在业务交易开始时向应用程序提供精确的库存计数。某些系统(例如 SAP)虽然避免使用数据库锁,但在其排队系统中获取应用程序锁。在数据库层中已开发了许多很棒的技术,可以帮助解决这种拥挤问题:乐观并发控制、脏读等。但没有一种技术可以真正完美工作,都具有负面影响。在某些情况下,你确实会想要锁定表,但这种情况应该比较少并且锁定操作之间相隔较远。

      Amazon.com 以一种非常简单的方式解决了这个问题:他们向用户提供了一个用户可以选择加入并且接受或拒绝的服务级别目标 (SLO)。该 SLO 主要表示为“通常在 N 小时中提供”-- 用户看不到书籍或其他商品的实际库存计数,但会向用户提供是否有货的信息。无需任何数据库锁,实际上,完全不需要任何数据库连接。如果系统不能满足 SLO,它会向买家表达歉意(通常通过电子邮件),并且提供更新的 SLO。

    • 可替代资源:字典按如下所示定义可替代:“可替代(尤指商品)是指某种特性或类型可整体或部分与其他相似特性或类型自由地交换或替代。”该想法的目标是再次减少访问共享数据的冲突,它的核心是使用信息模型提供了一种方法,让用户与数据的可替代实例交互而不是与特定实例交互。预订酒店房间是这方面的一个好例子。你可以提出许多要求,例如床位数、海景、吸烟/非吸烟等,但不会提及房间“123”。使用与上例相似的模型,完全可以缓存有关可替代数据池的信息,针对该数据池执行业务流程,只有在签入过程完成后,才从该池分配某个特定房间。在签入过程开始后就从池中删除某个特定房间的混合模型也完全是可行的。

  • 管理缓存

    在正确的时间缓存正确的信息是缓存策略取得成功的关键环节。加载缓存的技术有很多种:分布式环境中的 Caching 对此进行了很好的介绍。此外,下面的部分将概述依赖于分布式缓存的防故障 (FailSafe) 应用程序设计的若干注意事项。

    • 引用数据 - 如果托管环境(结构控制器或数据中心)遇到灾难情况,则你的应用程序将移到另一个环境。在你的应用程序的活动实例已经处于活动状态的情况下(主动-主动设计),你的缓存很可能已经包含许多相关数据(特别是引用数据)。在你的应用程序的新实例开始运转时,在缓存节点中将不会有任何信息。你应该对你的应用程序进行设计,以便在缺少缓存时,它自动加载所需数据。在新实例中,你可以具有一个启动例程,它将引用数据大容量加载到缓存中。最好将这两种方法结合起来使用,因为一旦应用程序由云基础结构提供服务,用户就可能处于活动状态。

    • 活动数据 - 上面介绍的引用数据基本技术也同样适用于活动数据。但对于活动数据有一个新思路。在我们的假设中,引用数据在应用程序的任何持久存储区中均可用。因为引用数据将不会频繁更改,所以同步应该不是问题,尽管仍需要考虑同步。但是,活动数据尽管单独进行更新并且更新频率较低,仍比引用数据更容易发生更改。理想情况下,分布式缓存会颇为频繁地保持活动数据的持久性,并且在应用程序的不同实例之间复制数据。请确保持久性和同步间隔保持合适的尺度。既要足够远,以免争用;又要足够近,以便尽量减少数据丢失。

我们对平台与应用程序之间的关系(尤其是在职责领域)常常存在一些误解。最让人头痛的一个方面就是数据。

尽管 Azure 之类的平台承诺存储数据的多个副本(并且在一些服务中甚至步子迈得更大,甚至会提供地理冗余),但存储的数据受到应用程序、工作负荷及其组件服务的制约。如果应用程序所执行的操作损坏了应用程序数据,则平台将存储其多个副本。

在确立你的故障模式和故障点时,标识应用程序中哪些方面可能导致数据损坏十分重要。尽管发源点可能多种多样,从错误代码或有害消息到你的服务等等,但标识相关故障模式和故障点十分重要。

应用程序级别补救

  • 幂等性

    对于所连接的服务而言,一个核心假设是这些服务不可能是 100% 可用,并且使用重试逻辑处理暂时性故障是核心的实现手段。在实现重试逻辑的情况下,可能会出现同一消息发送多次,以及消息乱序发送等情形。

    操作应设计为具有幂等性,确保多次发送同一条消息不会导致数据存储区出现意外或受到污染。

    例如,如果服务操作被调用了多次,那么所有请求中的插入数据操作可能导致添加多条记录。一种解决方法是在代码中实现智能“插入更新”(upsert),这种方法可以在记录存在时执行更新,而在记录不存在时执行插入。可以使用时间戳或全局标识符将新的消息从以前处理过的消息中区分出来,如果新消息中包含的记录在数据库中不存在,则将该记录插入数据库中;如果新消息中包含的记录在数据库中已经存在并且要比以前消息中的记录更新,则更新数据库中的现有记录。

  • 工作负荷活动和补偿行为

    除了幂等性之外,另一个要考虑的领域是补偿行为的概念。

    补偿行为的一个现实的例子就是在使用信用卡购买了产品之后再退货的情形。在这个情形中,一位消费者在一家零售商那里购买了一件产品,并且使用信用卡帐户付款。当该消费者将产品退还给零售商,此退货行为将接受退货策略的评估,如果退货行为符合该策略,则零售商将把货款返还到消费者的信用卡帐户。

    随着所连接的系统不断增长和组合服务不断涌现,了解如何处理补偿行为也变得越来越重要。

    对于许多业务线应用程序开发人员而言,事务的概念并不陌生,但参考框架通常与由本地数据技术公开的事务功能和相关代码库密切相关。当从云的角度考察此概念时,这一理念需要考虑与分布式服务的业务流程相关的新内容。

    服务业务流程可以跨多个分布式系统,且长期运行并具有状态。业务流程本身极少是同步的,它可以跨多个系统,且时间跨度根据业务方案可从几秒到几年。

    例如,一个供应链方案在同一个工作负荷活动中可能会涉及 25 个组织,因此可能会有 25 个或更多系统在一个或多个服务业务流程中相互连接。

    如果某个活动成功执行,就必须让这 25 个系统都知道。对于活动中的每个连接点,参与的系统可能会为它从其他系统收到的消息提供一个相关 ID。根据活动的类型,如果某个系统收到了相关 ID,该系统就可能会认为事务已经完成。在其他情况下,当完成所有 25 个系统的交互后,可能会向所有系统发送确认消息(要么直接从单个服务发送,要么通过每个系统的特定业务流程交互点发送)。

    为了处理组合活动和/或分布式活动中的故障,每个服务都会公开一个服务接口以及一个或多个操作,以便接收请求来根据唯一标识符取消给定的事务。在服务后方,可能需要设置工作流来补偿因取消此活动所带来的影响。在理想情况下,这些过程都是自动执行的,但也可以采用更为简单的方式,将这些过程路由到组织内的某个人来手动进行补救。

备份

除了应用程序级别的补救以免数据损坏外,还有另外一种补救措施,可以在应用程序补救不成功的情况下供你选择。

创建和还原数据存储区的备份副本(整体或部分)的过程应该是你的弹性计划的一部分。尽管备份和还原数据的概念已经不是新鲜事物,但在云中这个概念仍有一些新思路。

在制定备份策略时,应该对用于还原数据的业务要求有清醒的认识。如果某一数据存储区由于灾难情况而损坏或处于脱机状态,则你需要知道必须还原的数据类型、数据量以及需要采取的步骤。这将影响你的整个可用性计划,并且应该推动你制定备份和还原计划。

  • 关系数据库

    关系数据库的备份已是老生常谈。许多组织都备有用于备份数据的工具、方法和过程,以便满足灾难恢复或合规性需要。在许多情况下,传统的备份工具、方法和过程只需进行很少的修改或者根本无需修改即可使用。此外,还可以考虑一些新的或不同的替代方法,例如,在基于云的 blob 存储中备份数据和存储副本。

    在评估现有过程和工具时,评估哪个方法适合于基于云的解决方案十分重要。在许多情况下,针对不同的故障模式,可能需要采用下面的一种或多种方法。

    1. 完全备份 - 此备份是备份整个数据存储区。完全备份应该根据你的数据量和速度定期执行。完全备份是根据你的服务的服务级别协议而需要提供的完整数据集。此备份类型的机制通常由数据库/数据库服务提供商或其供应商生态系统提供。

    2. 时间点 - 时间点备份反映的是数据库在某一给定时间点的状态。例如,如果在下午发生了一个损坏数据存储区的错误,则可以还原在中午进行的时间点备份,以便最大程度地降低对业务的影响。

      随着用户的连接性不断增加,他们期望在任何时间都能够使用你的服务,这就促使你必须能够在出现故障的情况下迅速还原到最近的时间点。

    3. 同步 - 除了传统的备份以外,另一个选项是数据同步。例如,数据可以存储于多个数据中心中,并且定期从一个数据中心同步到另一个数据中心。除了在解决方案中提供同步数据(使用流量管理)作为一般可用性计划的一部分之外,还可以使用同步在存在业务连续性问题时故障转移到辅助数据中心。

      如果使用服务的用户的连接性保持稳定,停机时间在大多数情况下变得越来越不可接受,同步可以作为一种合乎需要的方法。

      同步模式可包括:

      - 在同一云提供商的不同数据中心之间同步

      - 在不同云提供商的数据中心之间同步

      - 在内部数据中心与云提供商的数据中心之间同步

      - 在数据中心与用户设备之间的用户特定数据分片同步

  • 分片的关系数据库

    对于许多人来说,迁移到云是为了应对大量用户和高流量的情况(例如,移动或社交应用程序)。在这些情况下,应用程序模式通常涉及从单个数据库模型移出到多个数据库分片,这些分片包含整个数据集的某一部分并且针对大规模使用进行了优化。在 Azure 上最近构建的一个社交网络项目启动时总共包含 400 个数据库分片。

    每个分片都是一个独立的数据库,而且你的体系结构和管理应该能够轻松地对各个分片以及包含所有分片的整个数据集进行完整备份、时间点备份和备份的还原。

  • 非 SQL 数据存储区

    除了关系数据存储区之外,也应该为“不仅是 SQL”或“非 SQL”数据存储区考虑备份策略。主要云提供商提供的最流行的非 SQL 数据库形式应是高可用性键值对存储区形式,通常称作表存储区。

    非 SQL 存储区可以是高度可用的。在一些情况下,它们还将是地理冗余的,这有助于在特定数据中心出现灾难情况下避免损失。这些存储区通常不提供相应的保护措施来应对应用程序意外覆盖或删除内容。应用程序或用户错误不会由平台服务(例如 blob 存储)自动处理,因此应该考虑制定备份策略。

    尽管关系数据库通常具有很好的现成工具来执行备份,但许多非 SQL 存储区却没有。通常采用的体系结构方法是在非 SQL 存储区副本中创建数据的副本,并且使用某种类型的查找表来标识源存储区中哪些行已放置于副本存储区中。若要还原数据,应使用同一个表,并且从该表进行读取以便标识副本存储区中可供还原的内容。

    根据业务连续性方面的考量,此副本的位置可由同一个云提供商托管、位于相同数据中心中和/或相同的非 SQL 数据存储区中。它也可以驻留在不同的数据中心、不同的云提供商和/或不同形式的非 SQL 数据存储区中。放置的位置很大程度上将会受到你的工作负荷服务的期望 SLA 或者任何相关法规遵从性方面的影响。

    在进行此决定时要考虑的一个因素是成本,特别是在成本与数据流入和流出相关时。云提供商可能允许在它们的数据中心内(或之间)免费移动数据,并且允许数据免费传入它们的环境中。但是没有云提供商提供免费的数据流出,并且将数据移到第二个云平台提供商的成本可能会因数据量大而很高。

    note备注
    查找表会成为潜在的故障点,并且其副本应视作弹性计划的一部分。

  • Blob 存储

    与关系数据存储区和非 SQL 数据存储区相似,一个常见的错误概念是,有了针对 Blob 存储产品的可用性功能,就不再需要考虑实现备份策略。

    Blob 存储也可能是地理冗余的,但如前所述,这不会保证没有应用程序错误。应用程序或用户错误不会由平台服务(例如 blob 存储)自动处理,因此应该考虑制定备份策略。

    备份策略可能与用于非 SQL 存储区的策略非常相似。由于 blob 的规模可能很大,因此,用于移动数据的成本和时间将是制订备份和还原策略时要考量的重要部分。

  • 还原备份

    目前,大多数人都听说过这样一个事情,某个组织建立并认真遵循备份策略,但从未对数据还原进行测试。在真的发生了灾难的日子,他们要还原数据库备份,但发现他们未正确配置备份,并且他们多年来发送到场外的磁带不含他们需要的信息。

    无论实施何种备份过程,必须进行还原测试,以便验证数据可以正确还原并且确保还原及时发生以及对业务的影响最小。

内容传递网络 (CDN) 是为经常请求的文件提供可用性和更好的用户体验的一种流行方式。CDN 中的内容在其首次使用时复制到某个本地节点上,然后从这个本地节点向后续请求提供数据。这些内容将在指定的时间段后到期,到期后,这些内容必须在下一次请求时再次复制到本地节点。

利用 CDN 将带来许多好处,但也会增加依赖项。像任何依赖项一样,应主动考查在出现服务故障时的补救措施。

适当地使用 CDN

一个常见的错误概念是 CDN 适合于所有规模。有这样一个例子,客户确信 CDN 是用于在线电子书店的合适的解决方案。但它不是。原因是什么?因为在一个包含上百万书籍的目录中,只有少量书籍会被经常请求(即“命中”),而那些很少被请求的书籍却占据着该目录的很长篇幅。经常请求的书籍会在首次请求时被复制到本地节点上,并且提供经济合算的本地规模以及愉悦的用户体验。而对于占据很长篇幅的那些很少被请求的书籍,几乎每个请求都被复制两次(一次复制到本地节点,然后再复制到客户),因为不频繁的请求导致内容经常到期。这个例子表明,不正确的 CDN 将会与你的预想结果背道而驰 – 导致速度更慢、成本更高的解决方案。

在许多情况下,在继续执行下一步工作之前可能没有规划某一解决方案的运行状况。为了构建真正具有弹性的应用程序,应该针对运行状况进行设计。针对运行状况进行设计通常将包括一些关键行为,例如建立运行状况模型、捕获遥测信息、整合运行状况监视服务和工作流,以及使这些数据可以让运营和开发人员进行操作。

开发团队常常忽视应用程序“运行状况”,甚至有时候会对其完全视而不见。因此,投入生产的服务常常就包含两个已知状态:正常运行或关闭。弹性服务的设计人员应该开发运行状况模型,这些模型定义应用程序运行状况条件、下降的运行状态、故障和运行状况依赖项。

主动地开发运行状况模型将勾画故障模式和故障点,并且要求开发人员在应用程序设计阶段中标识并研究“假设”应用场景。为使运行状况模型可操作,一个服务必须能够传达其运行状况。该服务必须具有可编程的方法来广播此类信息,为该运行状态提供接口以便以交互方式进行查询,提供管理员可用来实时监视应用程序运行状况的机制(或挂钩到现有机制),并且建立管理员在需要时可执行故障排除以便将应用程序返回到运行状态的机制。

定义特征

对于某一给定的服务或应用程序,应该执行诊断以便标识指示至少三个运行状况类别的数据点和值范围 - 正常运行、下降的正常运行和非正常。可以利用这些信息来自动实现服务的自我修复。

定义接口

定义了运行状态后,一个服务应该公开与运行状况相关的接口。这些接口将提供以下类别的操作。

  • 将运行状态传输到订阅的合作伙伴服务

    一个服务应该将运行状况信息传输到订阅的合作伙伴服务。此运行状态应该简明,具有概括性的运行状况和基本的诊断。

    该服务应该为合作伙伴服务提供订阅运行状况消息的能力。可通过适合于解决方案的途径来传递运行状况消息。一个途径可能会让该服务将运行状态更新放置于订户可检索的队列上。

    另一种方法是允许订户提供在其上公开已知运行状况报告接口的端点。在运行状况信息发生更改时,它可以向位于所提供端点上的订户发出信息。

  • 公开用于传递遥测数据的接口

    遥测非常适合于操作,因为它有助于在多个级别上标识应用程序和/或服务的当前运行状况。遥测还可以帮助迅速标识在环境中发生异常情况的时间。这可以帮助你非常细致地了解该服务的情况,并且向服务提供商的操作员工、服务和面板公开。

    对于操作,遥测度量可以包括不同角色、服务和基于服务建立的复合应用程序的平均 CPU 使用率百分比、错误数、连接数和队列数之类的信息。

    “特定于应用程序的”遥测通常不由平台本身直接自动启用和监视,因此,应该由服务和应用程序启用遥测。

  • 公开接口以便询问服务是否有其他的运行状况诊断信息

    理想上,一个服务还应提供接口以便询问其他运行状况诊断信息。基于在运行状态中接收的概括性信息的订户服务可以请求其他信息,以便使用与提供其运行状况详细信息的服务的关系确定某个过程是否继续前进。

    具体而言,如果该服务似乎处于不佳的运行状态,则借助于其他信息,正在使用的服务可决定是继续使用该服务还是故障转移到替代提供商。

  • 公开接口以便在服务和应用程序级别对服务运行状况进行补救

    如果运行状况信息的使用者是某个内部服务或相关服务,则你可能要启用该服务以便对已知问题进行自我补救。与我们所服的药物一样,对服务运行状况的理解将随着时间的推移而加深,并且运行状况数据可以导致不同的处理过程。

    服务可以公开接口以便允许提供这种处理。在其最简单的形式中,可涵盖从触发重新启动或服务的重新映像到故障转移到不同的内部数据或服务提供商等多种方法。

    理解服务的运行状况可使服务提供商能够迅速标识某一服务是否处于非正常状态。自动的操作可以提供对已知问题的快速、一致和指导性的补救,并使服务进行自我修复。下面的部分将更详细地介绍运行状况的不同方面。

遥测是“使用特殊设备测量某项内容(如压力、速度或温度),然后将这些数据通过无线电发送到另一个位置的过程”。

必须从你的服务收集遥测数据,这一点非常重要。遥测通常分为以下四种类型之一:用户、业务、应用程序和基础结构。

用户遥测针对单个目标用户的行为。这让你深入了解用户的行为,并且作为结果可以帮助提供个性化体验。

业务遥测包含与企业的业务活动和关键性能指标 (KPI) 相关的数据。业务遥测的示例包括站点上唯一活动用户的数目、已观看的视频数等。

应用程序遥测包含有关应用程序层及其相关服务的运行状况、性能及活动的详细信息。例如,应用程序遥测将包含有关数据客户端调用和登录、异常、API 调用、会话等的详细信息。

基础结构遥测包括有关底层系统基础结构的运行状况的详细信息。这可能包括有关 CPU、内存、网络、可用容量等资源的数据。

确定收集什么数据以及如何收集数据时,请务必了解数据以及你打算对数据执行什么操作。

首先,确定收集数据的目的是告知操作还是发起操作。要问的问题是:“我应以多快的速度反应?”你是否将使用接近实时的数据来潜在地发起操作?此外,你是否将使用逐月趋势报告中的数据?这些问题的答案将会告知体系结构中使用的遥测方法和技术。

下一步,确定你打算应用于所收集的遥测数据的问题类型。你是将使用遥测来回答已知问题,还是将遥测用于探索。例如,对于业务而言,KPI 是已知问题的答案。但是,想要研究设备数据以找到导致故障的模式的制造商会闯入未知的领域。对于制造商来说,故障来源于系统中的一个或多个项目。制造商正在进行探索,将需要附加数据。

当你使用遥测来获得见解时,必须考虑获得该见解所需的时间。在某些情况下,你将利用遥测检测到设备传感器读数有秒钟或几分钟时长的激增现象。在其他情况下,你可以使用遥测来确定具有较长处理时间的网站的每周用户增长。

最后,请考虑要获得见解可以从时间范围内的信号源收集的数据量。你必须了解所需的源信号的量。然后,可以确定对该信号进行分区的最佳方式,并建立本地计算和全局计算的合理搭配。

另一个考量是如何在遥测中记录事件的顺序。许多组织默认使用时间戳。但是,时间戳可能是一个难题,因为所有数据中心中的服务器时钟并不一致。虽然时间可能会定期同步,但有确凿的证据显示,服务器时钟会偏移(慢慢变得越来越不准确)。这种偏移会导致可能削弱有效的分析的更改。对于要求精度的应用场景,请考虑使用替代解决方案,如利用向量时钟实现。

确定遥测方法后,可以继续将信号特性化。

你可以将信号分类为连续信号或离散信号。连续信号的一个示例是实时事件数据。日志文件条目属于离散信号。

若要满足方法需求,你必须确定信号中有多少数据。如果信息是连续的,则必须建立采样率。如果信息是离散的,则必须确定要保留或筛选的记录。

你还必须确定访问类型。在某些情况下,非常适合推送遥测数据。在其他情况下,你将通过拉取来检索遥测数据。

在更进化的系统中,你可能会发现从现有的推送遥测获得的见解可能会导致定向拉取其他信息。例如,如果推送遥测指示非最佳状态,你可以通过拉取来检索其他诊断数据。

所有收集到的数据在某些条件下可能会相关,但并非总是必须发送所有遥测数据。根据遥测类型以及要获取见解所需的数据量,你可能能够检索较少的数据量。你可以使用本地计算生成聚合、采样或子集,并将该数据发送到服务。例如,如果从标准遥测收到的数据指示非最佳状态,则服务可以请求额外的数据。

在开发遥测策略时,请考虑什么样的策略是适当的。遥测需要可用连接,但通过该连接发送数据会产生费用。创建考虑上下文、连接性和成本的策略,并根据需要调整遥测。

你的策略必须考虑当前状态的上下文,以确定什么遥测适合立即发送。从以前收到的遥测及关联的业务需求获得的见解将通知上下文。此上下文可帮助引导遥测收集并确定其优先次序。

这些设备可以建立不同类型的连接(WiFi、LTE、4G、3G 等),并且该连接可以是可变的。设备的连接现在与确定应传输哪些数据相关。在连接不可靠或连接速度较低的应用场景中,策略可以确定所传输遥测的优先级。

通常提供连接要收费。策略将考虑连接当前是否按流量计费。如果连接按流量计费,则策略将确定相关费用和使用上限(如果可用)。许多设备在一天之中使用了不同类型的连接。你可以根据传递特定遥测的费用优先传递或取消优先传递该遥测。

不同受众通常会插入遥测数据并将其可视化。操作员和开发人员是可视化对其很重要的两类受众。但是,如下所述,每个受众的需求要求不同的粒度级别。

将概括性的运行状况和更细致的遥测数据可视化对于操作人员而言十分重要。自动通知可能会根据遥测数据准备就绪。但是,操作员会想要一个有助于直观显示当前和历史服务性能的仪表板。

对于具有相当规模的应用程序,此信息可帮助快速确定当前问题或预测未来问题。它还可以帮助操作员确定潜在影响和根本原因。

性能仪表板关系图

图 10

上图来自一个大型的社交网站,图中可以看到 API 角色的平均 CPU 使用百分比、API 错误数、在线用户数、Web 活动连接数、Web 角色的 CPU 使用百分比、Web 错误数、Web 硬连接数、Web 池连接数、Web 应用程序队列、Web 软连接数。

在操作无需对服务本身进行代码修改即可对错误进行补救的情形下,遥测和上面所示的报告类型特别有帮助。操作可执行的活动示例可以包括部署更多角色和回收实例。

你可以利用历史和实时遥测数据的可视化进行以下操作:

  • 故障排除。

  • 对活动站点问题进行事后调查分析。

  • 培训新的操作人员。

除了操作员工之外,软件开发人员也是遥测数据的重要使用者。错误可能与操作环境无关,而可能与基础应用程序代码相关。通过针对开发人员的遥测面板,这些开发人员能够执行目标明确的操作。

下面是专为此类目的创建的示例实用工具的两个屏幕快照。该面板提供有关错误数目、错误所属类别以及与各类别相关的特定数据的详细信息。这些数据包括检查数据,其中包含错误总数、经历错误的角色实例的总数以及具有错误的数据库的总数等。

仪表板关系图

图 11

仪表板关系图

图 12

对于参与用户高达数百万的大型网站,更高的错误计数将会发生,并且是完全可接受的。通过对遥测进行解释的以开发人员为中心的面板,可帮助标识是否真的存在问题、是否适合介入以及代码中发生问题的位置。

另请参阅

显示: