[转]缓存技术探讨(五)

2.6.1  选择使用模式
2.6.1.1 使用InProc模式
当使用进程内模式时,状态信息保存在aspnet_wp.exe的进程中。由于在web场的情况下aspnet_wp.exe的多个实例在同一台服务器上运行,所以进程内模式不适用与web场的情况。

进程内模式是唯一支持Session_End事件的session模式,当用户会话超时或中止时,可以运行Session_End中的事件处理代码来清除资源。

2.6.1.2 使用StateServer模式
StateServer模式使用指定的进程储存状态信息。因为它也是一种进程外模式,所以要保证你存储的对象是可序列化的,以支持跨进程传输。

当使用Session对象在web场的情况下使用时,必须保证web.config文件中的<MachineKey>元素在所有服务器上是唯一的。这样所有的服务器使用同样的加密方式,才能访问缓存中的数据。参考msdn中的“MachineKey元素”。

2.6.1.3 使用SQL Server模式
SQL Server模式下,当你使用信任连接(trusted_connection=true 或 integrated security=sspi)访问Session state信息时,不能在asp.net中使用身份用户模拟。

默认情况下,SQL Server将状态信息存储在TempDb数据库中,它在每次Sql server服务启动时会自动重新创建,当然,你可以指定自己的数据库以便在数据库重启的过程中也能保持数据。

2.6.2  决定使用Session对象要存储的内容
你可以使用Session对象缓存任何类型的.net框架数据,但是要了解对某种类型来说最好的方式是什么。有以下几点需要说明:

1、  对基本类型(比如Int,Byte,String)来说,可以使用任何方式。因为在选用进程外方式时,asp.net使用一个优化的内部方法来序列化和反序列化基本类型的数据;

2、  对复杂类型(如ArrayList)来说,只选用进程内方式。因为asp.net使用BinaryFormatter来序列化和反序列化这类数据,而这会影响性能的。当然,只有在State Server和SQL Server的方式下,才会进行序列化操作;

3、  缓存的安全问题,当在缓存中存储敏感数据时,需要考虑安全性,其它页面可以访问到缓存中的数据;

4、  避免缓存大数据,那会降低性能;

5、  这种缓存方式不支持过期策略、清除和依赖。

2.6.3  实现Session State
Asp.net提供了简单接口来操作Session State,并可使用Web.Config进行简单设置,当配置文件中的设置改变时,能够在页面上立刻体现出来,而不需要重新启动asp.net进程。

以下代码演示了使用SQL Server来实现Session数据的存储和使用。

 1<sessionState mode="SQLServer" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1; Integrated Security=SSPI" cookieless="false" timeout="20"/>
 2private void SaveSession(string CartID)
 3{
 4   Session["ShoppingCartID"= CartID;
 5}

 6private void CheckOut()
 7{
 8   string CartID = (string)Session["ShoppingCartID"];
 9   if(CartID != null)
10   {
11      // Transfer execution to payment page.
12      Server.Transfer("Payment.aspx");
13   }

14   else
15   {
16      // Display error message.
17   }

18}

2.7使用Asp.net客户端缓存和状态
你还可以使用客户端存储页面信息的方式来降低服务器的负担,这种方法提供最低的安全保障,但却有最快的性能表现。由于需要将数据发送到客户端存储,所以数据量有限。

实现客户端缓存的机制有以下五种,接下来将依次介绍:

·隐藏栏位(Hidden Field)

·View State

·隐藏帧(Hidden Frame)

·Cookies

·Query String

这五种方式分别适合于存储不同类型的数据。

2.7.1  使用Hidden Field
你可以将经常改变的少量数据保存在HtmlInputHidden中来维护页面的状态。当每次页面回送的过程中,这些数据都会包含在表单中大送到服务器,所以你要使用HTTP POST方式来提交页面。

使用这种方式的优点如下:

不需要服务器资源,直接从页面中读取;
几乎所有的浏览器都支持;
实现简单;
由于数据在页面中,所以在web Farm的情况下也可使用。
缺点:

由于可以通过查看源码看到,所以可能会被篡改;
不支持复杂格式的数据,复杂数据必须使用解析字符串的方式来间接得到;
当存储大数据的时候会影响性能。
示例:

<input id="HiddenValue" type="hidden" value="Initial Value" runat="server" NAME="HiddenValue">

2.7.2  使用View State
所有的Web Form页面和控件都包含有一个ViewState属性,在对同一页面多次请求时可以保持页面内的值。它的内部实现是维护相应的hidden field,只不过是加密了的,所以比hidden field的安全性要好。

使用View State的性能表现很大程度上依赖于服务器控件的类型。一般来说,Label,TextBox,CheckBox,RadioButton,HyperLink的性能要好一些,而DropdownList,ListBox,DataGrid和DataList就要差很多,因为包含的数据量太大,所以每次页面回送都很耗时间。

有些情况下不推荐使用ViewState,比如:

1、  不需要回送的页面避免使用;

2、  避免使用ViewState保存大数据量;

3、  在需要使用会话超时的情况下避免使用它,因为它没有超时操作。

ViewState的性能表现和Hidden Field的是类似的,但是具有更高的安全性。

优点:

数据在页面中自动维护,不需要服务器资源;
实现简单;
数据是经过加密和压缩的,比hidden field有更高的安全性;
数据存在客户端,可以在Web Farm情况下使用。
缺点:

存储大数据量时会降低性能;
和hidden field类似,在客户端数据仍然有潜在的安全威胁。
示例代码如下:

 1public class ViewStateSample : System.Web.UI.Page
 2{
 3   private void Page_Load(object sender, System.EventArgs e)
 4   {
 5      if (!Page.IsPostBack)
 6      {
 7         // Save some data in the ViewState property.
 8         this.ViewState["EnterTime"= DateTime.Now.ToString();
 9         this.ViewState["UserName"= "John Smith";
10         this.ViewState["Country"= "USA";
11      }

12   }

13
14    private void btnRefresh_Click(object sender, System.EventArgs e)
15   {
16      // Get the saved data in the view state and display it.
17      this.lblTime.Text = this.ViewState["EnterTime"].ToString();
18      this.lblUserName.Text = this.ViewState["UserName"].ToString();
19      this.lblCountry.Text = this.ViewState["Country"].ToString();
20   }

21}
posted on 2008-06-18 19:57  Xuemin_Zhang  阅读(243)  评论(0编辑  收藏  举报