用缓冲技术提高JSP应用的性能和稳定性

一、概述

在Web应用中,有些报表的生成可能需要数据库花很长时间才能计算出来;有的网站提供天气信息,它需要访问远程服务器进行SOAP调用才能得到温度信息。所有这一切都属于复杂信息的例子。在Web页面中加入过多的复杂信息可能导致Web服务器、数据库服务器负荷过重。JSP代码块缓冲为开发者带来了随意地增加各种复杂信息的自由。

JSP能够在标记库内封装和运行复杂的Java代码,它使得JSP页面文件更容易维护,使得非专业开发人员使用JSP页面文件更加方便。现在已经有许多标记库,它们或者是商业产品,或者是源代码开放产品。但这些产品中的大多数都只是用标记库的形式实现原本可以用一个简单的Java Scriptlet实现的功能,很少有产品以某种创造性的方式使用定制标记,提供在出现JSP定制标记库之前几乎不可能实现的用法。

OSCache标记库由OpenSymphony设计,它是一种开创性的JSP定制标记应用,提供了在现有JSP页面之内实现快速内存缓冲的功能。虽然已经有一些供应商在提供各种形式的缓存产品,但是,它们都属于面向特定供应商的产品。OSCache能够在任何JSP 1.1兼容的服务器上运行,它不仅能够为所有用户缓冲现有JSP代码块,而且能够以用户为单位进行缓冲。OSCache还包含一些提高可伸缩性的高级特性,比如:缓冲到磁盘,可编程的缓冲刷新,异常控制,等等。另外,正如OpenSymphony的其他产品,OSCache的代码也在一个开放源代码许可协议之下免费发行。

本文以一个假想的拍卖网站设计过程为例,介绍OSCache的工作过程。这个假想的Web网站将包含:一个报告最近拍卖活动的管理页面;一个功能完整、带有各种宣传信息的主页;一个特殊的导航条,它包含了用户所有尚未成交的拍卖活动信息。

二、管理页面


拍卖网站包含一个管理报表,数据库服务器需要数秒时间才能创建这样一个报表。报表生成时间长这一点很重要,因为我们可能让多个管理员监视系统运行情况,同时又想避免管理员每次访问时都重新生成这个报表。为了实现这一点,我们将把整个页面封装到一个应用级的缓冲标记之内,这个缓冲标记每隔1小时刷新。其他供应商提供的一些产品也具有类似的功能,只是OSCache比它们做得更好。

为简单计,我们将不过多地关注格式问题。在编写管理页面时,我们首先把标记库声明加入到页面:

<%@ taglib uri="cachetags" prefix="cache" %>

接下来我们要用cache标记来包围整个页面。cache标记的默认缓冲时间是1小时。

<cache:cache> .... 复杂的管理报表 .... </cache:cache>

现在管理页面已经被缓冲。如果管理员在页面生成后的一个小时之内再次访问同一页面,他看到的将是以前缓存的页面,不需要由数据库服务器再次生成这个报表。

三、主页


拍卖网站的主页显示网站活动情况,宣传那些即将结束的拍卖活动。我们希望显示出正在进行的拍卖活动数量,当前登录用户数量,在短期内就要结束的拍卖活动的清单,以及当前时间。这些信息有着不同的时间精确度要求。网站上的拍卖活动通常持续数天,因此我们可以把缓冲有效拍卖活动数量的时间定为6个小时。用户数量的变化显然要频繁一些,但这里我们将把这个数值每次缓冲15分钟。最后,我们希望页面中显示的当前时间总是精确的页面访问时间。

在主页中声明标记库之后,我们首先以不带缓冲的方式直接输出当前日期:

现在是:<%=new java.util.Date()%>

接下来,我们要显示一个清单,列出那些将在短期内结束的拍卖活动:

<cache:cache> <ul> <% // 构造一个包含最近拍卖活动的Iterator Iterator auctions = .... while (auctions.hasMore()) { Auction auction = (Auction)auctions.next(); %><li><%=auction%></li%< } %> </ul> </cache:cache>

最后,我们希望显示出正在进行的拍卖活动的数量,这个数字需要缓冲6小时。由于cache标记需要的是缓冲数据的秒数,我们把6小时转换成21600秒:

<cache:cache time="21600"> <% //查询数据库得到拍卖活动总数 int auctionCount = .... %> 本网站正在进行的拍卖活动有<%=auctionCount%>个! </cache>

可以看到,我们只用少量的代码就构造出了一个带有复杂缓冲系统的主页。这个缓冲系统对页面各个部分分别进行缓冲,而且各个部分的缓冲时间完全符合它们各自的信息变化频繁程度。由于有了缓冲,现在我们可以在主页中放入更多的内容;而在以前没有缓冲的情况下,主页中放入过多的内容会导致页面访问速度变慢,甚至可能给数据库服务器带来过重的负载。

四、导航条


假设在规划网站的时候,我们决定在左边导航条的下方显示购物车内容。我们将显示出用户所拍卖的每一种商品的出价次数和当前报价,以及所有那些当前用户出价最高的商品的清单。

我们利用会话级的缓冲能力在导航条中构造上述功能。把下面的代码放入模板或者包含文件,以便网站中的其他页面引用这个导航条:

<cache:cache key="navbar" scope="session" time="300"> <% //提取并显示当前的出价信息 %> </cache:cache>

在这里我们引入了两个重要的属性,即key和scope。在本文前面的代码中,由于cache标记能够自动为代码块创建唯一的key,所以我们不需要手工设置这个key属性。但在这里,我们想要从网站的其余部分引用这个被缓冲的代码块,因此我们显式定义了该cache标记的key属性。第二,scope属性用来告诉cache标记当前代码块必须以用户为单位缓冲,而不是为所有用户缓冲一次。

在使用会话级缓冲时应该非常小心,应该清楚:虽然我们可以让复杂的导航条减少5倍或10倍的服务器负载,但它将极大地增加每个会话所需要的内存空间。在CPU能力方面增加可能的并发用户数量无疑很理想,但是,一旦在内存支持能力方面让并发用户数量降低到了CPU的限制之下,这个方案就不再理想。

正如本文前面所提到的,我们希望从网站的其余部分引用这个缓冲的代码块。这是因为,当一个用户增加了一个供拍卖的商品、或者出价竞购其他用户拍卖的商品时,我们希望刷新缓冲,使得导航条下一次被读取时具有最新的内容。虽然这些数据可能因为其他用户的活动而改变,但如果用户在网站上执行某个动作之后看到自己的清单仍未改变,他可能会感到非常困惑。

OSCache库提供的flush标记能够刷新缓冲内容。我们可以把下面的代码加入到处理用户动作且可能影响这一区域的页面之中:

<cache:flush key="navbar" scope="session" />

当用户下次访问它时,navbar缓冲块将被刷新。

至此为止,我们这个示例网站的构造工作已经完成且可以开始运行。下面我们来看看OSCache的异常处理能力。即使缓冲的内容已经作废,比如在缓冲块内出现了Java异常,OSCache标记库仍旧允许我们用编程的方法显示这些内容。有了这种异常控制功能,我们可以拆除数据库服务器和Web服务器之间的连接,而网站仍能够继续运行。JSP 1.2规范引入了TryCatchFinally接口,这个接口允许标记本身检测和处理Java异常。因此,标记可以结合这种异常处理代码,使得JSP页面更简单、更富有条理。

OpenSymphony正在计划实现其他的缓冲机制以及一个可管理性更好的主系统,它将使我们能够对缓冲使用的RAM和磁盘空间进行管理。一旦有了这些功能,我们就能够进一步提高网站的响应速度和可靠性。

【结束语】OSCache能够帮助我们构造出更丰富多彩、具有更高性能的网站。有了OSCache标记库的帮助,现在我们能够用它解决一些影响网站响应能力的问题,比如访问量高峰期、数据库服务器负荷过重等。

(0)

相关推荐

  • 用缓冲技术提高JSP应用的性能和稳定性

    一.概述在Web应用中,有些报表的生成可能需要数据库花很长时间才能计算出来:有的网站提供天气信息,它需要访问远程服务器进行SOAP调用才能得到温度信息.所有这一切都属于复杂信息的例子.在Web页面中加入过多的复杂信息可能导致Web服务器.数据库服务器负荷过重.JSP代码块缓冲为开发者带来了随意地增加各种复杂信息的自由. JSP能够在标记库内封装和运行复杂的Java代码,它使得JSP页面文件更容易维护,使得非专业开发人员使用JSP页面文件更加方便.现在已经有许多标记库,它们或者是商业产品,或者是源

  • js的压缩及jquery压缩探讨(提高页面加载性能/保护劳动成果)

    问题缘由:负责公司的开发平台研发工作,考虑的知识产权的保护工作,必须要考虑java的加密技术和js脚本的加密技术.在目前java加密很容易破解的情况下,还是先搞定js的加密和压缩,一方面可以提高页面加载性能,另外一方面也希望辛苦研发出来的成果得到一定的保护. 研究过程: 1.先强烈鄙视一下哪些随便转载文章的家伙,给我制造了很大的麻烦!!网上很多帖子都不靠谱.. 2.首先想了解jquery使用什么压缩的, 网上找了半天,说法不一样,后来还是在jquery官网的最频繁问题中找到了答案,但这已经是绕了

  • 举例解析Java的图像缓冲技术的使用

    当图像信息量较大,采用以上直接显示的方法,可能前面一部分显示后,显示后面一部分时,由于后面一部分还未从文件读出,使显示呈斑驳现象.为了提高显示效果,许多应用程序都采用图像缓冲技术,即先把图像完整装入内存,在缓冲区中绘制图像或图形,然后将缓冲区中绘制好的图像或图形一次性输出在屏幕上.缓冲技术不仅可以解决闪烁问题,并且由于在计算机内存中创建图像,程序可以对图像进行像素级处理,完成复杂的图像变换后再显示. [例]小应用程序程序演示图像缓冲显示技术.程序运行时,当鼠标在图像区域内按下时,图像会出现边框,

  • 利用 SQL Server 过滤索引提高查询语句的性能分析

    大家好,我是只谈技术不剪发的 Tony 老师. Microsoft SQL Server 过滤索引(筛选索引)是指基于满足特定条件的数据行进行索引.与全表索引(默认创建)相比,设计良好的筛选索引可以提高查询性能.减少索引维护开销并可降低索引存储开销.本文就给大家介绍一下 Microsoft SQL Server 中的过滤索引功能. 在创建过滤索引之前,我们需要了解它的适用场景. 在某个字段中只有少量相关值需要查询时,可以针对值的子集创建过滤索引. 例如,当字段中的值大部分为 NULL 并且查询只

  • PHP使用memcache缓存技术提高响应速度的方法

    本文实例讲述了PHP使用memcache缓存技术提高响应速度的方法.分享给大家供大家参考.具体分析如下: php虽然己经做到很好很快了,但是如果大数据量时还是会有些卡了,这里介绍一下PHP中使用memcache缓存技术提高响应速度方法,有需要了解的朋友可参考. memcache既可以在linux下使用,也可以在windows系统下使用,当然首推linux系统,至于如何安装memcache,google一下就什么都出来了. 下面贴一段memcache的使用例子,代码如下: 复制代码 代码如下: <

  • C#双缓冲技术实例详解

    本文实例分析了C#双缓冲技术.分享给大家供大家参考,具体如下: 双缓冲解决闪烁问题. 整理: GDI+的双缓冲问题 一直以来的误区:.net1.1 和 .net 2.0 在处理控件双缓冲上是有区别的. .net 1.1 中,使用:this.SetStyle(ControlStyles.DoubleBuffer, true); .net 2.0中,使用:this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 导致画面闪烁的关键原因分析:

  • 双缓冲技术实现Android 画板应用

    什么是双缓冲技术?双缓冲技术就是当用户操作界面完成后,会有一个缓冲区保存用户操作的结果. 为什么要使用双缓冲技术?拿Android 游戏开发来说,界面贞每次都是全部重画的,也就说画了新的,旧的就没了,所以需要使用双缓冲技术保存之前的内容. 如何实现双缓冲?使用一个Bitmap对象保留之前的画布即可. package com.example.phonegaptest; import android.content.Context; import android.graphics.Bitmap; i

  • Android采用双缓冲技术实现画板

    本文实例为大家分享了Android实现画板的具体代码,采用的技术是双缓冲技术,供大家参考,具体内容如下 1.双缓冲技术的概念 所谓的双缓冲技术其实很简单,当程序需要在指定的View上进行绘制时,程序并不需要直接绘制到该View组件,而是先绘制到一个内存中的Bitmap图片上(就是缓冲),等内存中的Bitmap绘制好之后,再一次性将Bitmap绘制到View组件上. 2.Android采用双缓冲实现画板  实现的思路: 1).定义一个内存中图片,将他作为缓冲区Bitmap cacheBitmap

  • C#手工双缓冲技术用法实例分析

    本文实例讲述了C#手工双缓冲技术.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace advanced_drawing { public partial class F

  • C#默认双缓冲技术实例分析

    本文实例讲述了C#默认双缓冲技术.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace advanced_drawing { public partial class F

随机推荐