|
动态的 Web 应用程序能够存储大量信息,让用户能够通过熟悉的界面立即访问这些信息。但是,随着应用程序越来越受欢迎,可能会发现对请求的响应速度没有以前那么快了。开发人员应该了解 Web 应用程序处理 Web 请求的方式,知道在 Web 应用程序开发中可以做什么,不能做什么,这有助于减少日后的麻烦。 静态的 Web 请求(比如图 1 所示的请求)很容易理解。客户机连接服务器(通常通过 TCP 端口 80),使用 HTTP 协议发出一个简单的请求。
图 1. 客户机通过 HTTP 请求静态的文件
服务器解析这个请求,把它映射到文件系统上的一个文件。然后,服务器向客户机发送一些描述有效负载(比如网页或图像)的响应头,最后向客户机发送文件。
在上面的场景中可能出现几个瓶颈。如果请求的变化很大,导致无法有效地使用操作系统的磁盘缓存,那么服务器的磁盘会很忙,到了某种程度之后,就会减慢整个过程。如果为客户机提供数据的网络通道饱和了,就会影响所有客户机。但是,除了这些状况之外,“接收请求,发送文件” 过程还是相当高效的。
通过做一些假设,可以大致体会静态服务器的性能。假设一个请求的服务时间是 10ms(主要受到磁头寻道时间的限制),那么大约每秒 100 个请求就会使磁盘接近饱和(10msec/request / 1 second = 100 requests/second)。如果要发送 10K 的文档,就会产生大约 8mbit/sec 的 Web 通信流(100 requests/second * 10 KBytes/request * 8bits/byte)。如果可以从内存缓存中获取文件,就可以降低平均服务时间,因此增加服务器每秒能够处理的连接数。如果您有磁盘服务时间或平均请求延时的真实数据,可以把它们放进上面的算式,从而计算出更准确的性能估计值。
既然服务器的处理容量是平均请求服务时间的倒数,那么如果服务时间加倍,服务器的处理容量(每秒处理的连接数)就会减半。请记住这一点,下面看看动态应用程序的情况。
动态应用程序的流程依赖于应用程序的具体情况,但是一般情况下与图 2 相似。
图 2. 客户机通过 HTTP 请求动态页面
与前一个示例中的客户机一样,图 2 中的客户机首先发出一个请求。静态请求和动态请求之间实际上没什么差异(有时候 .php 或 .cgi 等扩展名可能意味着动态请求,但是它们可能引起误解)。如何处理请求是由 Web 服务器决定的。
在 图 2 中,请求被发送到一个应用服务器,比如运行一个 Java™ 应用程序的 Solaris 系统。应用服务器执行一些处理,然后向数据库查询更多的信息。得到这些信息之后,应用服务器生成一个 HTML 页面,这个页面由 Web 服务器转发给客户机。因此,这个请求的服务时间是几个部分的总和。如果数据库访问花费 7ms,应用服务器花费 13ms,Web 服务器花费 5ms,那么网页的服务时间就是 25ms。根据前面介绍的倒数规则,各个组件的容量分别是每秒 142、77 和 200 个请求。因此,瓶颈是应用服务器,它使这个系统每秒只能处理 77 个连接;超过这个数量之后,Web 服务器被迫等待,连接开始排队。
但是,一定要注意一点:因为系统每秒只能分派 77 个连接,而一个连接需要的处理时间是 25ms,所以并非每个应用程序用户的请求都能够在 25ms 内得到处理。每个组件每次只能处理一个连接,所以在高峰负载下,请求不得不等待 CPU 时间。在上面的示例中,考虑到排队时间和 25ms 的处理时间,平均请求服务时间最终会超过 1.1 秒。关于解决这些排队问题的更多信息,请参见 参考资料。
通过这些示例可以得出以下结论:
在用户发出请求和获得最终页面之间的步骤越多,整个过程就越慢,系统容量就越低。
随着页面请求速率的增加,这种效应会越来越显著。
在项目开始时做出的体系结构决策也会影响站点处理负载的能力。
本文的其余部分将深入讨论这些问题。 |
|