REL 5: 您如何在分布式系统中进行交互设计,从而缓解或经受住故障影响?
分布式系统依赖于通信网络以便使组件互相连接(如服务器或服务等)。尽管这些网络中存在数据丢失或延迟,但是您的工作负载必须可靠运行。分布式系统组件的运行方式不得对其他组件或工作负载产生负面影响。这些最佳实践使工作负载能够承受压力或故障,从中更快地恢复,并且降低此类伤害的影响。其结果是缩短平均恢复时间 (MTTR)。
资源
Retry, backoff, and jitter: AWS re:Invent 2019: Introducing The Amazon Builders’ Library
(DOP328)
Error Retries and Exponential Backoff in AWS
Amazon API Gateway: Throttle API Requests for Better Throughput
The Amazon Builders' Library: Timeouts, retries, and backoff with jitter
The Amazon Builders' Library: Avoiding fallback in distributed systems
The Amazon Builders' Library: Avoiding insurmountable queue backlogs
The Amazon Builders' Library: Caching challenges and strategies
Well-Architected lab: Level 300: Implementing Health Checks and Managing Dependencies
to Improve Reliability
CircuitBreaker (summarizes Circuit Breaker from “Release It!” book)
Michael Nygard “Release It! Design and Deploy Production-Ready Software”
最佳实践:
-
实现轻松降级以将适用的硬依赖关系转换为软依赖关系: 某个组件的依赖关系运行不正常时,该组件仍可在性能降低的条件下运行。例如,当依赖关系调用失败时,进行故障转移,使用预先确定的静态响应。
-
限制请求: 这是对按需求意外增加做出响应的缓解模式。部分请求会得到执行,但超出定义限制的请求会被拒绝,并返回说明它们已被限制的消息。客户端预期将会回退,并且放弃请求或以较低速率进行重试。
-
控制与限制重试调用: 在逐渐延长的间隔以后使用指数回退进行重试。引入抖动使此类重试间隔随机化,并限制重试的最大次数。
-
快速试错和限制队列: 如果工作负载无法成功响应请求,则快速试错。这样可释放与请求关联的资源,并允许该服务在资源不足的情况下恢复。如果工作负载能够成功响应,但请求速率过高,则使用队列来对请求进行缓冲。不过,不要允许使用长队列,它可能导致处理已被客户端放弃的过时请求。
-
设置客户端超时: 适当设置超时,对它们进行系统性验证,而且不要依赖默认值,因为它们通常设置得过高
-
尽可能使服务为无状态: 服务应该不需要状态或在不同的客户端请求之间卸载状态,在磁盘上或内存中本地存储的数据不存在依赖关系。从而支持任意替换服务器,而且不会对可用性产生影响。Amazon ElastiCache 或 Amazon DynamoDB 是卸载状态的理想目标位置。
-
实施紧急杠杆: 这些是可帮助您的工作负载减轻可用性影响的快速流程。即使未找到根本原因,它们也可以运行。理想的紧急杠杆可通过提供完全确定的激活与停用标准,将解析器的认知负担降低到零。杠杆示例包括,阻止所有的机器人流量或静态响应处理。杠杆通常需要手动操作,但也可实现自动化。
改进计划
实现轻松降级以将适用的硬依赖关系转换为软依赖关系
- 通过返回静态响应,您的工作负载会缓解其依赖项中发生的故障
Well-Architected lab: Level 300: Implementing Health Checks and Managing Dependencies to Improve Reliability - 检测重试操作可能何时失败,并防止您的客户端使用断路器模式进行失败调用
CircuitBreaker
限制请求
- 使用 Amazon API Gateway
Throttle API Requests for Better Throughput
控制与限制重试调用
Error Retries and Exponential Backoff in AWS
- Amazon 开发工具包默认执行这一功能。在调用自己的依赖服务时,您需要在依赖关系层中执行类似的逻辑。根据您的使用案例确定超时以及何时停止重试。
快速试错和限制队列
- 在服务面临压力时执行快速试错
Fail Fast - 限制队列: 在基于队列的系统中,如果在停止处理后消息仍不断涌入,则消息债务可能造成大量积压,从而增加处理时间。工作完成太晚,以至于结果无法发挥作用,从根本上导致了队列原本要避免的可用性命中问题。
The Amazon Builders' Library: Avoiding insurmountable queue backlogs
设置客户端超时
AWS SDK: Retries and Timeouts
尽可能使服务为无状态
- 删除可能存储在请求参数中的状态。
- 某些数据(例如 cookie)可能在标头或查询参数中传递。
- 进行重构,从而删除可能在请求中快速传递的状态。
- 在检查是否确实需要状态之后,将任何状态追踪移动到具有弹性的多可用区缓存或数据存储(如 Amazon ElastiCache、Amazon RDS、Amazon DynamoDB
或第三方分布式数据解决方案): 存储无法移动到弹性数据存储的状态。
- 提交请求时实际上并不需要某些数据,这些数据可以按需检索。
- 删除可以异步检索的数据。
- 确定满足所需状态要求的数据存储。
- 考虑针对非关系型数据使用 NoSQL 数据库。
实施紧急杠杆
- 关于实施和使用紧急杠杆的提示
- 当杠杆被激活时,求少不求多
- 保持简单,避免双模态行为
- 定期测试您的杠杆
- 以下为非紧急杠杆的操作示例
- 添加容量
- 号召依赖您的服务的客户端服务所有者,要求他们降低调用
- 更改代码并将其释放