软件架构伸缩性的六大法则(上)
极客时间编辑部
讲述:初明明大小:4.91M时长:05:22
你好,欢迎收听极客视点。
对于绝大多数商业和政府系统来说,在开发和部署的早期阶段,可伸缩性并不是主要的需求,可用性和实用的新功能才是开发周期的驱动因素。只要能够满足正常的负载,就会不断加入新功能来提高系统的业务价值。
但是,系统也会发展到性能和可伸缩性成为紧迫问题甚至是生存问题的阶段,此时,架构师就有责任将系统演化成一个响应迅速、可伸缩的系统。
成本和伸缩性之间的关系
对系统进行伸缩的一个核心原则是能够方便地添加新资源来处理增长的负载。对于很多系统来说,一个简单而有效的方法是部署多个无状态服务器实例,并使用负载均衡器在这些实例之间分配请求,如下图。
假设这些资源部署在云平台上,那么成本就是:
每个服务器实例的虚拟机部署成本。
负载均衡器的成本,由新请求和活跃请求的数量以及所处理的数据量决定。
在这个场景中,随着请求负载的增长,已部署的虚拟机需要拥有更大的处理能力,这导致了更高的成本。负载均衡器的开销也会随着请求负载和数据大小成比例增长。
因此,成本和规模是相辅相成的。可伸缩性的设计决策不可避免地会影响部署成本。如果忽略了这一点,你可能会收到意想不到的巨额部署账单。
那么该如何降低成本?主要有两种方式:
使用弹性负载均衡器,根据实时请求负载来调整服务器实例的数量。
增加每个服务器实例的容量。这通常是通过调优服务器部署参数 (例如线程数、连接数、堆大小等) 来实现。仔细选择参数设置可以显著提高性能,从而提高容量。
注意系统瓶颈
对一个系统进行伸缩本质上就是要增加它的容量。在上面的示例中,我们通过部署更多的服务器实例来提高请求处理能力。但是,软件系统是由多个相互依赖的处理元素或微服务组成的,所以在增加一部分微服务容量的同时,不可避免地会被其他一些微服务拖累。
在我们的负载均衡示例中,假设服务器实例都连接到同一个共享数据库。随着部署服务器数量的增加,数据库的请求负载也随之增加 (如下图)。
在某个阶段,数据库将达到饱和,数据库访问将开始出现更大的延迟。现在,数据库成为瓶颈——即使你增加更多的服务器处理能力也无济于事。如果要进一步伸缩,就需要以某种方式增加数据库的容量。你可以尝试优化查询,或者增加更多的 CPU 或内存。你也可以对数据库进行复制或分片。除了这些,还有其他很多解决方案。
系统中的共享资源都可能成为瓶颈。当你在架构中的某些部分增加容量时,需要仔细考虑下游的容量,确保不会突然给系统造成冲击。因为这样会迅速导致级联故障 (参见下一条规则),并导致整个系统崩溃。
数据库、消息队列、长延迟网络连接、线程和连接池以及共享微服务都是潜在的瓶颈。可以肯定的是,高流量负载会很快让这些瓶颈暴露出来。关键的是要能够在瓶颈暴露出来的时候能够防止系统突然崩溃,并快速部署更多的能力。
慢服务比故障服务更有害
在正常情况下,系统应该能够为微服务和数据库提供稳定、低延迟的通信。当系统负载保持在正常的配置水平时,性能是可预测、一致和快速的,如下图所示。
当客户端负载超过正常水平时,微服务之间的请求延迟将开始增加。特别是如果传入的请求负载继续超过容量 (服务 B),未完成的请求将在微服务 A 中堆积,由于下游延迟变慢,该微服务现在接收的请求比已完成的请求还要多。
当一个服务由于抖动或资源耗尽而不堪重负,服务就会无法响应客户端,客户端也将陷入停滞。直接导致的结果就是级联故障——慢服务会导致请求沿着请求路径不断累积,直到整个系统崩溃。
一些架构模式(如回路断路器和隔板)可用于防止级联故障。如果服务的延迟超过指定值,断路器就会调节请求负载,甚至是将其断开。当只有一个下游依赖项发生故障时,隔板可以保护上游的微服务不发生故障。这些措施可用来构建弹性和高度可伸缩的架构。
以上是“软件架构伸缩性的六大原则”中的前三个,受篇幅所限,其余三大原则将在下文分享,欢迎持续关注。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
该免费文章来自《极客视点》,如需阅读全部文章,
请先领取课程
请先领取课程
免费领取
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
精选留言
由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论