扩展 Web 应用程序的架构问题
标签(空格分隔): Architecture Scaling Web Applications
我将在这篇博客中揭露出当我们扩展和性能调优大型 Web 应用程序时遇到的架构问题。
让我们通过定义几个术语来创造共同的理解和词汇开始。稍后当扩展 Web 应用程序时,我将通过不同的问题抛出,像:
- 架构瓶颈
- 扩展数据库
- CPU 限制应用
- IO 限制应用
确定一个 Web 应用程序的最佳线程池将在下一篇博客讨论。
性能
术语 Web 应用程序性能是指的几件事情。大多数开发人员关心的主要是响应时间和可伸缩性。
-
响应时间
是指 web 应用程序处理请求和返回响应所花费的时间。应用程序应该在可接受的时间范围内响应请求(响应时间)。如果应用程序超过了可接受的时间范围,它是被认为性能不行或是降级的。
-
可扩展性
Web 应用程序如果能被添加更多硬件,是被认为有可扩展性,应用程序可以比以前线性的处理更多请求。有两种方式增加硬件:
- Scaling Up(垂直扩展):在单个系统里面增加 CPU 数量或是换更快的 CPU
- Scaling Out(水平扩展):增加系统数
垂直扩展 VS 水平扩展
水平扩展是被认为更重要的,当商品硬件本身相对于特殊配置的硬件(超级电脑)便宜的时候。但是增加单个系统一个应用程序的所能处理的请求数也是重要的。一个应用程序被认为性能优良,如果它仅仅通过增加资源就能在不降级响应时间的前提下处理更多的请求。
响应时间 VS 可扩展性
响应时间和可扩展性不是总在一起的。比如应用程序或许有可接受的响应时间,但可能无法处理超过一定数量的请求,或是应用程序可以处理增加的请求数,但是响应时间非常长。我们必须在可扩展性和响应时间之间的取得平衡来获取更好的应用程序性能
容量规划
容量规范是一个计算出所需要的硬件来处理生产预期的负荷的实践。通常它涉及计算出更少系统的情况下应用程序的性能和基于每个系统突出性能。最后,满载/性能测试验证它。
易扩展的架构
如果在一个多层架构中每层都是可扩展的,那么应用程序是可扩展的(水平扩展)。例如:像下图显示的,通过在应用层和数据库层添加系统,我们应该有线性扩展能力。
扩展负载均衡器
负载均衡器可以被水平扩展通过把 DNS 指向多个 IP 地址和使用 DNS 轮询 IP 地址。其他选项是前面另一个负载均衡器分发负载下一级负载平衡器。
添加多个负载平衡器是罕见的,因为单个系统运行 nginx 或 HAProxy 可以处理超过 20K 的并发连接,相比于每个系统只有 Web 应用程序处理几千个并发连接。因此单个负债均衡系统可以处理多个 Web 应用程序系统。
扩展数据库
扩展数据库是需要面对的常见问题之一。添加业务逻辑(存储过程、函数)在数据库层带来额外的开销和复杂性
关系型数据库
关系型数据库可以通过主-从模式扩展,在主服务器上可读写,在从服务器上只读。主从模式提供有限的读扩展,开发人员必须将数据库分成多个数据库。
NoSQL
CAP 定理 显示了是不可能同时获得一致性,可用性和分区容错的。NoSql 数据库通常是在一致性方面妥协来获得高可用性和分区。
拆分数据库
数据库可以被垂直(分区)和水平(分片)拆分:
- 垂直拆分(分区) - 基于领域概念,数据库可以被拆分成多个松耦合的子数据库。比如:客户数据库,产品数据库等。另外一个拆分数据库的方式是移动实体的几列到一个数据库,另外一些列到另外一个数据库。比如:客户数据库,客户联系方式数据库,客户订单数据库等。
- 水平拆分(分片) - 数据库可以被水平拆分进多个数据库中基于一些离散的属性。比如:美国客户数据库,欧洲客户数据库。
使用分区或分片从单个数据库到多个数据库过渡是一项很有挑战的任务。
架构瓶颈
由于两个问题会形成扩展瓶颈:
- 中央化组件:在应用架构中的一个添加了请求上限数的组件不能被水平扩展,整个架构和请求管道可以被处理。
- 高延迟组件:在请求管道中的慢组件将降低应用程序的响应时间限制。通常的解决方案是使得高延迟的组件进入后台任务或在队列中异步执行它们。
CPU 限制应用
如果一个应用程序的吞吐量被它的 CPU 限制了,那就认为这个应用是 CPU 限制的。通过提升 CPU 的速度,应用响应时间可以被降低。
几个场景中的应用可能是 CPU 限制:
- 执行计算和处理数据但是没有执行 I/O 操作的应用程序(金融 或交易应用程序)。
- 重度使用缓存并且没有执行 I/O 操作的应用程序
- 异步(非阻塞)的应用程序,不需要等待额外的资源(被动模式应用。NodeJS 应用)
在以上的场景中,应用程序已经在有效的工作,但在一些情况下应用程序写得很糟糕的或者低效的代码执行不必要的繁重计算或是循环在每次请求时往往表现出较高的CPU使用率。通过分析应用程序很容易找出不足并修复它们。
这些问题可以被修复:
- 缓存预先计算的值
- 在单独的后台任务中执行计算
不同方式的缓存,缓存怎样可以降低负载以及提升性能和 web 应用程序的可伸缩性在这篇博客中 Caching To Scale Web Applications。
I/O 限制应用
如果一个应用的吞吐量被它的 I/O 或是网络操作和提升 CPU 速度不能降低应用程序的响应时间,那该应用就被认为是 I/O 限制的。大部分应用是 I/O 限制的,由于 CRUD 操作,在大部分应用性能调优或扩展 I/O 限制应用程序是项非常难的工作,由于它依赖于下游其他系统。
几个场景中的应用可能是 I/O 限制:
- 依赖于数据库和执行 CRUD 操作的应用程序
- 消费下游的 Web 服务来执行其操作的应用程序
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。