共计 1719 个字符,预计需要花费 5 分钟才能阅读完成。
简介
对于“服务框架”,最难的一点是,如何给各个参数提供适当的默认值。特地是如果该参数会影响到性能或者服务的可用性。比方:
- Client-side Timeout
- 服务端容许的最大连接数
过载剖析(The anatomy of overload)
在设计零碎时,咱们要将其设计为在遭逢过载状况之前被动扩大,来防止过载的产生。为了达到这一目标,咱们须要采取很多措施,包含:
- 主动扩大
- 适当的加重负载
- 监控机制
- 继续测试
通过对服务进行负载测试不难发现,低负载的服务器提早低于高负载的服务器。这是因为在该负载下,线程相互之间争用资源,导致须要进行频繁的上下文切换,垃圾回收和 I / O 争用也会变得更加显著。最终服务会达到一个拐点,在负载超过拐点后,服务的性能会开始疾速的降落。
该察看背地的实践称为“Universal Scalability Law”,它衍生自 Amdahl’s law,该实践指出,只管能够通过应用并行化来进步零碎的吞吐量,但零碎吞吐量最终会受制于串行化的吞吐量。(即受制于无奈并行化的工作)
While a system’s throughput can be increased by using parallelization, it is ultimately limited by the throughput of the points of serialization (that is, by the tasks that can’t be parallelized)
其次,吞吐量不仅受制于系统资源的限度,因为当零碎过载时,吞吐量通常会降落。尽管超载时计算机仍然能够失常工作,然而其会破费大量的工夫用于上下文切换,导致系统速度太慢从而不可用。
在分布式系统中,客户端常常会设置有超时工夫。当服务器过载时,latency 会超过超时工夫,申请会开始失败。下图显示了服务器的响应工夫,如何随着吞吐量的变大而变大。
在上图中,当 latency 超过 timeout 时,申请将会大量失败。对与客户端来说,通过下图更能分明的反馈出服务的可用性,在这里应用 median response time,其含意为 50% 的 latency 低于中值。如果将客户端的超时工夫设置为 median response time,则一半申请将超时,因而可用性为 50%。通过下图,能够将服务端的提早问题转换为客户端的可用性问题。
形容可用性的一种更易懂的形式是辨别 无效吞吐量 和吞吐量。
- 吞吐量(goodput):是每秒发送到服务器的申请总数。
- 无效吞吐量(throughput):是吞吐量的子集,它在承受解决的过程中没有产生谬误,而且具备足够低的提早(低于超时工夫),能够发送正确的相应给客户端。
正反馈循环
过载状况存在的问题在于它在反馈环路中会自我放大。如果客户端发来的申请超时,服务器在该申请上做的大量工作都将是有效工作。而零碎在过载状况下,最不应该做的就是有效工作。
更蹩脚的是,客户端常常会对超时申请进行重试,这使得对系统的申请大量减少,使其远超过零碎所能接受的负载。而且,如果在面向服务的体系结构(SOA)中有足够深的调用图(即,A -> B -> C …),并且如果每个层都执行了多次重试(侥幸的是,这一点在后面的文章中曾经提出了一些解决办法:https://segmentfault.com/a/11…),则底层的过载将导致级联重试,从而会以指数模式放大申请的数量。
当这些因素联合在一起时,过载会造成正反馈循环,从而导致系统不可复原。
避免做有效工作
从外表上来看,load shedding 很简略。只有当服务器靠近过载时,让它回绝多余的申请即可。load shedding 的目标非常简单,避免客户端超时。通过这种办法,服务器能够为承受的申请放弃高可用性,而只会影响多余流量的可用性。
通过缩小多余负载来管制提早,能够使零碎可用性更高。上图中总体可用百分比是在降落,这看起来比拟蹩脚,但要害是服务对决定承受的申请放弃了高可用。从而防止了服务器做有效工作。
通过 load shedding,即便总的吞吐量减少,服务器也能够维持肯定数量的无效吞吐量的解决。然而,load shedding 并不是没有任何代价的,服务器最终还是会受限于 Amdahl’s law,使无效吞吐量呈现降落。