尽管缓存管理在Windows应用程序中已经不再是个问题,但在web环境下依然是个挑战。因为HTTP是一个无状态的协议并且web服务无法识别不同请求的用户。识别不同的请求究竟是哪个特定用户发出的,并且存储这些信息以便它在以后请求中能被重新使用,对我们来说非常重要。ASP.NET提供了很多特性用来在客户端和服务器端存储这些数据,但是有时我们会对“我们什么时候使用它们(哪个)”感到疑惑。在ASP.NET中,我们会遇到像Session,Application以及Cache这些对象,为了有效地在web应用中有效地使用它们,理解他们之间的不同对我们来说非常重要。
背景
在这篇文章中,我将谈到在ASP.NET中不同的缓存管理方法。在web应用中,有时需要在服务端存储数据以避免从数据库检索数据和数据格式化逻辑所需的开销来提高性能,同时在接下来的请求中我们可以跨用户、跨应用、跨机器地重用同样的数据。所以,为了实现这个目的我们需要在服务端缓存数据。
缓存帮我们在3个方面实现了提高服务质量
•性能(Performance)-通过减少检索数据和格式化操作开销,缓存提高了应用程序的性能。
•可伸缩性(Scalability)-由于缓存减少了检索数据和格式化操作的开销,它降低了服务端的负载,因而提高了应用程序的可伸缩性。
•可用性(Availability)-由于应用程序从缓存中读取数据,应用程序可以在其它系统或数据库连接失败时继续运行。
不同方法
在web应用中,我们可以在服务端和客户端缓存数据、页面等。我们分别来看一下在服务端和客户端缓存。
服务端缓存管理
ASP.NET Session state
Session用来缓存每个用户的信息。这意味着这些数据是不能跨用户共享的,它只限定了创建这个会话(Session)的用户来使用它。ASP.NET中Session就是用来区分用户的。
Session能用三种方式来托管:
•进程内(Inproc)-会话状态存储在aspnet_wp.exe进程中。当应用程序域回收时Session数据会丢失。
•状态服务器(StateServer)-会话状态存储在不同的进程内,可以在不同的机器上。因为它可以存储在不同的机器上,所以这个选项支持网站群。
•Sql数据库(SQLServer)-会话状态存储在SqlServer数据库中,这个选项也支持网站群。
对于状态服务器和Sql数据库来说,这两者都需要对缓存的对象进行序列化,因为要缓存的数据是要缓存到应用程序进程之外的。这两种方式都会影响性能因为数据检索与存储需要话费更多时间相对进程内缓存来说。所以要根据具体需要以确定使用哪种缓存方式。
下面示例代码展示了如何使用Session
复制代码 代码如下:
string empNum = Request.QueryString["empnum"];
if (empNum != null)
{
string details = null;
if (Session["EMP_DETAILS"] == null)
{
//Get Employee Details for employee number passed
details = GetEmployeeDetails(Convert.ToInt32(empNum));
Session["EMP_DETAILS"] = details;
}
else
{
details = Session["EMP_DETAILS"];
}
//send it to the browser
Response.Write(details);
}
ASP.NET application object
ASP.NET提供了一个叫Application的对象用来存储所有用户都可以访问的数据。这个对象的生命周期与应用程序的生命周期一样,当应用程序启动时这个对象会被重新创建。与Session对象不同,Application对象可以被所有用户请求,因为这个对象是在应用程序域中创建和管理的,因而它也是不能在Web网站群中使用的。Application对象非常适合存储应用程序元数据(Config file data),这种数据可以被装载到Application对象中并且在整个应用程序周期中每个用户请求都可以访问其中的对象而不用重新装载。但是如果有这样的需求:在应用程序运行中无论什么时候对Config文件做了修改缓存数据必需失效,这时Application方式就不能提供这样的支持了。在这种情况下,就要考虑cache对象了,下面介绍cache对象的使用。
ASP.NET cache object
ASP.NET cache object是我最喜欢的缓存机制,这是为什么我在这里要多说一些的原因。ASP.NET提供了一个键-值对(key-value pair)对象--cache对象,它可以在system.web.caching名称空间中得到。它的范围是应用程序域,生命周期和应用程序生命周期一致。与Session对象不同,它是可以被不同用户来访问的。