读发布!设计与部署稳定的分布式系统(第2版)笔记15_快速失败和替换

博客园   2023-06-29 07:10:44


【资料图】

1.快速失败而非缓慢响应

1.1.如果响应缓慢比没有响应更糟,那么最坏的情况肯定是缓慢的失败响应

1.2.如果系统能够预先确定某次调用会失败,那么最好快速失败

2.快速失败模式通过避免响应缓慢来提高整个系统的稳定性

2.1.当系统由于部分失效而面临压力时,快速失败模式还有助于保持系统容量

2.2.与超时模式配合使用,快速失败模式有助于避免层叠失效

3.预留资源并尽早验证集成点有效

3.1.确保在开始之前就能完成事务

3.1.1.关键资源不可用,比如所需调用的断路器已跳闸,那么就不要再浪费精力去调用

3.2.在事务的开始阶段和中间阶段,关键资源可用状态发生变化的可能性极小

3.3.应用程序或服务可以从传入的请求或消息中,大致了解需要哪些数据库连接和外部集成点,然后可以快速检查所需的连接,并查看集成点周围的断路器状态

4.使用输入验证

4.1.即使在预留资源之前,也要进行基本的用户输入验证

4.2.找到未输入的必需参数才是关键

5.任其崩溃并替换

5.1.有时,为了实现系统级稳定性,放弃组件级稳定性就是所能做的最好的事情

5.1.1.通过组件崩溃保护系统

5.1.2.通过组件级不稳定性构建系统级稳定性

5.1.3.这可能是将系统恢复到已知良好状态的最佳方式

5.1.4.隔离组件以实现独立崩溃

5.2.在Erlang语言中,这被称为“任其崩溃并替换”的哲学

5.2.1.任其崩溃并替换的方法认为错误恢复难以完成且不可信赖,所以我们的目标应该是尽快回到刚完成启动时的干净状态

5.3.程序所能拥有的最干净的状态,就是在刚刚完成启动的那一刻

5.4.前提

5.4.1.有限的粒度

5.4.1.1.必须为崩溃定义边界

5.4.1.2.发生崩溃的组件应该是独立的,系统的其余部分必须能够自我防护,避免受到层叠失效的影响

5.4.1.3.在微服务架构中,服务的整个实例可能是正确的崩溃粒度

5.4.1.4.在Erlang和Elixir中,崩溃的自然边界就是actor

5.4.2.快速替换

5.4.2.1.actor这样的进程内组件,重启时间以微秒为单位

5.4.2.2.在容器中运行Go二进制文件

5.4.2.2.1.启动一个新容器及其内部一个进程的时间以毫秒为单位计算,此时就可以通过让整个容器崩溃实现快速替换

5.4.2.3.NodeJS服务在AWS中一个长时间运行的虚拟机上运行

5.4.2.3.1.启动NodeJS进程需要花几毫秒,但启动一台新的虚拟机则需要几分钟
5.4.2.3.2.只需要让NodeJS进程崩溃,就可以实现快速替换

5.4.2.4.不要让单体系统崩溃

5.4.2.4.1.运行时负载较大或启动时间较长的大型进程,不适合运用“任其崩溃并替换”策略
5.4.2.4.2.将许多特性耦合到单个进程中的应用程序,也不推荐运用该策略
5.4.2.4.3.在数据中心的几台虚拟机上,运行着一个老旧的前端安装API的JavaEE应用程序
5.4.2.4.3.1.启动时间以分钟为单位计算,此时,“任其崩溃并替换”并不是正确的策略

5.4.3.监管

5.4.3.1.监管器不是服务的消费者

5.4.3.2.管理工人与要求服务是两码事

5.4.3.3.如果把两者混淆,就会损害系统

5.4.4.重新归队

5.4.4.1.在一个actor或实例先崩溃然后由监管器重新将其启动之后,系统必须要恢复对新启动的服务提供方的调用

5.4.4.2.如果实例被直接调用,则调用方的断路器应该自动将该实例重新归队

5.4.4.3.如果实例是负载均衡池中的一部分,那么必须能够将实例加回池中,接受工作

猜你喜欢
最新资讯