对 Web 应用程序进行性能调优

动态的 Web 应用程序能够存储大量信息,让用户能够通过熟悉的界面立即访问这些信息。但是,随着应用程序越来越受欢迎,可能会发现对请求的响应速度没有以前那么快了。开发人员应该了解 Web 应用程序处理 Web 请求的方式,知道在 Web 应用程序开发中可以做什么,不能做什么,这有助于减少日后的麻烦。

静态的 Web 请求(比如图 1 所示的请求)很容易理解。客户机连接服务器(通常通过 TCP 端口 80),使用 HTTP 协议发出一个简单的请求。

图 1. 客户机通过 HTTP 请求静态的文件

显示请求等待 Web 服务器处理它们,然后等待 Web 容器,依此类推。如果进入某个队列的请求速率超过了此队列处理请求的速率,请求就会聚集起来。当出现请求聚集时,服务时间是不可预测的,用户会察觉到浏览器会话延迟。 中的队列代表最糟糕的情况,因为 Web 服务器可以自己处理一些请求,即不需要访问数据库。

队列在 UNIX® 环境中很常见。当应用程序发出磁盘请求的速率快于磁盘返回数据的速率时,操作系统会让磁盘请求排队,还可能调整请求的次序以降低寻道时间。另一个队列是运行队列,其中包含等待运行的进程的有序列表。应用程序会等待轮到它们使用某些有限的资源(比如 CPU)。

因此,队列调优是一种平衡的艺术。队列太小,就会在仍然有富余容量的情况下拒绝用户。队列太大,就会试图为过多的用户提供服务,导致性能很差。

导致情况更复杂的另一个因素是,这些排队位置并不是无成本的。保留排队位置会导致内存开销,对于应用服务器,这会与正在处理请求的线程争用内存。因此,在一般情况下,在应用服务器上排队并不是好方法。推荐的方法是在应用服务器之前(比如在 Web 服务器上)排队。这意味着 Web 服务器要保持与 Web 客户机的连接,并在应用服务器空闲时发出请求。应用服务器只需处理它能够及时派发的请求。

IBM 的文档中推荐了 Web 应用程序布局方法和各种队列的调优方法。但是注意,IBM 建议应该避免在 WebSphere 中排队。这意味着应该把发送给 WebSphere 应用服务器的请求速率控制在能够立即处理的范围内。Web 服务器(或 Web 服务器前面的代理服务器)应该限制过多的连接,让它们等待处理。这确保负载比较重的应用服务器队列能够把时间花在为有限的请求提供服务上,而不是试图同时为所有请求提供服务。

针对开发人员的提示

作为开发人员,应该按照一些一般原则提高应用程序的可伸缩性。这些原则可以应用于大多数 Web 应用程序。

度量设施

应用程序应该以某种方式向收集系统提供度量值(即使收集系统仅仅是日志文件)。这些度量值包括访问应用程序中某个函数的频率或处理一个请求花费的时间等。这并不会使应用程序运行得更快,但是有助于了解应用程序为什么会变慢以及代码的哪些部分花费的时间最长。了解什么时候调用某些函数,这有助于把在系统上观察到的现象(比如 CPU 忙或磁盘活动量高)与应用程序中的活动(比如上传图像)联系起来。

能够了解站点上发生的情况,这是扩展站点容量的关键。您认为不够优化的代码部分可能不会造成问题。只有通过适当的度量,才能发现真正的瓶颈。

会话

Web 在本质上是无状态的。用户发出的每个请求都独立于以前的请求。但是,应用程序常常是有状态的。用户必须登录应用程序以证明自己的身份,在访问站点期间可能要维护购物车的状态,还可能要填写供以后使用的个人信息。跟踪会话是一种成本很高的操作,尤其是在涉及多个服务器的情况下。

在单一服务器上运行的 Web 应用程序可以把会话信息放在内存中,在服务器上运行的任何 Web 应用程序实例都可以访问共享内存。常常会给用户分配一个标志,这个标志标识内存中的会话。考虑一下在涉及第二个应用服务器时会发生什么。如果用户的第一个请求发送给一个服务器,第二个请求发送给另一个服务器,那么会存在两个单独的会话,它们并不相同。

此问题的常用解决方案是,把会话存储在数据库而不是内存中。这种方法导致的问题是,对于每个请求,需要增加数据库读操作,还可能涉及数据库写操作。每个 Web 应用服务器都需要这个数据库。

一个解决方案是,只在需要会话的地方使用会话。应用程序并不为每个请求装载会话,而是只在需要会话时装载会话。这会减少对后端数据库的请求数量。

另一个方法是加密会话数据并把它发送回客户机,这样就不需要在本地存储会话。在用户的 cookie 中能够存储的数据量是有限的,但是 RFC 2109 规定客户机应该能够为每个域名存储至少 20 个 cookie,每个 cookie 至少可以保存 4K 字节的数据。

如果发现用数据库存储的会话是性能瓶颈,而且无法消除它们,那么应该考虑把它们分散到单独的数据库,甚至是多个数据库。例如,可以在一个数据库中存储偶数的会话 ID,在另一个数据库中存储奇数的会话 ID。

缓存

与其他部分相比,应用程序的某些部分会更频繁地修改数据。新闻网站可能每个月只修改顶级分类列表一次。因此,对于每个请求都通过查询数据库获取最新的分类列表是很浪费的。同样,包含新闻稿的页面在其整个生命周期中可能只修改一两次,所以不需要为每个请求重新生成它。

缓存意味着把处理成本很高的请求的结果存储起来,供以后使用。可以缓存分类列表或整个页面。

接受自己的失败面,是一种成熟,更是一种睿智;

对 Web 应用程序进行性能调优

相关文章:

你感兴趣的文章:

标签云: