在软件架构畛域的中文文档、书籍中,常常能够看到“弹性”这个专业术语,但在不同的语境下含意可能会不同。
在英语中,elastic 和 resilient 两个单词都能够翻译为“弹性的”,然而它们在软件架构中代表的含意却齐全不同,须要防止混同。
Elastic
Elastic 代表的“弹性”强调的是 可伸缩性。
在《Designing Data-Intensive Applications》一书中,对 elastic 的定义:
Some systems are elastic, meaning that they can automatically add computing resources when they detect a load increase, whereas other systems are scaled manually (a human analyzes the capacity and decides to add more machines to the system). An elastic system can be useful if load is highly unpredictable, but manually scaled systems are simpler and may have fewer operational surprises.
翻译:某些零碎具备弹性,意味着它检测到负载减少时,能够自动化地减少计算资源。而非弹性的零碎则须要手动扩大(人工剖析性能并决定向零碎中增加更多的机器)。当零碎负载很难预测时,弹性零碎会十分有用,而手动扩大的零碎更加简略,并且能够缩小操作上的意外。
Elastic 示意零碎能够依据负载状况和相干策略主动调整计算资源,所以也称为 Auto Scaling。例如一个电商利用会在大促时有更大的负载量,则须要主动增加更多的服务器等资源保障系统失常提供服务,而在平时负载量小的时候,则主动缩小资源来管制老本。当咱们看到“弹性伸缩”这个术语时,要晓得这里的“弹性”代表的意思就是 elastic。
例如,Kubernetes 提供了 HorizontalPodAutoscaler,反对 Pod 程度主动扩缩容。阿里云等商业云平台也都提供了相似的弹性伸缩服务(Elastic Scaling Service),可依据负载状况和策略主动调整计算能力(即实例数量)。
Resilient
Elastic 代表的“弹性”强调的是 还原能力。
在《Designing Data-Intensive Applications》一书中,对 resilient 的定义:
The things that can go wrong are called faults, and systems that anticipate faults and can cope with them are called fault-tolerant or resilient.
翻译:可能出错的事件被称为故障,零碎可能预测并应答故障的能力称为容错或弹性。
Resilient 示意零碎有容错和故障恢复能力,从而零碎具备可靠性。
例如,Java 驰名的开源库 Hystrix 的介绍是这样的:
Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
这里的 resilience 当然指的不是弹性伸缩能力,而是容错能力。
除 Hystrix 外,其它开源的容错库:
- Resilience4j: Resilience4j is a fault tolerance library designed for Java8 and functional programming.
- Sentinel: A powerful flow control component enabling reliability, resilience and monitoring for microservices.
- Polly: Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.
- go-resiliency: Resiliency patterns for golang.
- Semian: Resiliency toolkit for Ruby for failing fast.
实现 resilient 的策略通常包含断路器(Circuit Breaker)、限流器(Rate Limiter)、重试(Retry)、舱壁(Bulkhead)等,更多可参考:https://github.com/App-vNext/…。
上面简略介绍罕用的几种容错的策略:
- 重试(Retry):很多谬误是短暂的并且能够主动复原的,对这种问题采纳重试策略。
- 断路器(Circuit Breaker):相似于电路或股市中的“熔断”概念,当零碎产生重大故障(大量超时或失败)时,为了防止后续继续一直的申请导致故障零碎过载,超时导致网络、线程资源占用,最终产生雪崩,而在一段时间内间接 fail fast(疾速失败,即间接返回谬误而不再去申请故障的零碎模块)。
- 舱壁(Bulkhead):《泰坦尼克号》电影中有一段对船体的形容:船体蕴含 16 个互相隔离的水密舱,即便有 4 个水密舱受损进水也能保障船沉没在海面上。架构设计中舱壁模式参考的就是这种形式,将资源进行隔离,例如能够为调用多个服务的消费者调配每个服务独立的连接池,从而保障一种故障只会影响到其对应的资源,而不会造成级联故障。
- 限流器(Rate Limiter):通过限流算法(如令牌桶算法、漏桶算法),限度在特定时间段内的执行次数、数据量等指标,从而避免零碎过载。