通过缓存的使用让管理员和客户满意






2.40/5 (6投票s)
2004年9月23日
7分钟阅读

28907

268
代码管理优化注意事项
引言
作为一名从服务器和数据库领域转到 Web 编程的程序员,我仍然尽可能地通过代码来优化事物。这主要是因为管理员们总是会考虑到预算、人员和吞吐量等问题。毕竟,管理员们不喜欢那些因为代码问题而需要在凌晨三点前赶来重置系统的人。而且从业务角度来看,如果你的代码不良地影响了客户的业务关系,你可能会阻碍自己的晋升机会。
本文使用的资源
Steven Walther 的《ASP.NET Unleashed》(第二版)的第 17 章引起了我的共鸣。它讨论了缓存,特别是那些不使用整个页面缓存的缓存方法。
继续
我们都知道,通过包含(includes)可以使用 .ascx 页面来将页面中重复使用的部分进行模块化。毕竟,反复复制粘贴页眉和页脚的代码项目会很麻烦。如果你不使用 .ascx 页面进行代码重用,那你一定是为生活所迫或者别的什么。我个人来说,我不得不处理电话和电子邮件,所以任何能给我更多时间的事情都是一种恩赐。
当然,在我的主 .aspx 页面中,我只需要写 `<%@ OutputCache Duration="300" VaryByParam="None" %>` 就可以省去一些打字的工作。但正如 Steven 所指出的,如果你的收入来源依赖于横幅广告怎么办?如果你不断展示相同的横幅广告,你的其他客户可能会因为缺乏点击量而流失。毕竟,在这个模式下,你的公司可能会因此获得报酬,或者这也可以用来减少管理员的工作量。而且,如果你的某个客户的广告活动有时限怎么办?如果你的布局有时效性怎么办?例如,对于一个抽奖活动,如果它依赖于节日/活动主题,或者横幅广告是一个可以打印出来寄送的时间特定优惠券。客户不希望它永远运行,而你也不想等到午夜才手动删除广告或 XML 文件。
如何进行逐项缓存 cache.Insert( "myItem", "运行那个新广告!", _ New cacheDependancy( MapPath( "myAdFile.xml" ) ) ) |
因此,如果 "myAdFile.xml" 项目被修改,*mytItem* 将从缓存中自动删除。 |
这些项目使用 cacheDependancy 类进行文件依赖 | |
如何基于 cache.Insert( "myItem", "运行那个新广告", _ |
在这种情况下,如果字符串数组中的任何一个 XML 文件被修改,*myItem* 都会从缓存中删除。 |
因此,实际上你可以用它来替换一个 XML 文件而使用另一个备用文件。或者,你可以为一年中的节日期间设置一个特殊的颜色方案,其中背景颜色或其他页面属性会充满节日气氛。当然,也会有你不在座位上而某个事件(如节日)即将到来的时候。对我来说,那是圣诞节和大学橄榄球碗赛(我指的是新年)。是时候从红色/白色/绿色(圣诞老人)切换到黑色/银色/金色(新年宝宝)了。现在我需要一个触发器。
现在,让我们在 SQL Server 中做一些工作来设置一些*触发器*,这将是实现这一目标的辅助工具。触发器基本上是一个存储过程,它会在对*表*或*视图*进行删除、插入或更新时自动执行。
[个人选择:广泛使用*视图*,这样实际的表就不会被触及,并确保首先验证用户输入的所有内容。
另请参阅: http://msdn.microsoft.com/events/devdays/sessions/default.aspx
AND
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/ThreatCounter.asp
用于创建“防黑客”的 ASP.NET,以获得更多安全方面的考虑]
如果你愿意,你也可以查看 *xp_cmdshell*,它将一个字符串作为操作系统命令来运行,将文件写入一个目录。
所以,MakeChng.sql 项目看起来是这样的
CREATE TRIGGER UpdateCache
On *Products*
FOR UPDATE, DELETE, INSERT
AS
DECLARE @CMD Varchar( 200 )
SELECT @cmd = 'echo ' + Cast( getDate( ) As Varchar 50 ) ) +
' > c:\layoutChng.txt'
EXEC master..xp_cmdshell @cmd, no_output
layoutDepndsOn.aspx 页面将是
<% Import Namespace="System.Data" %>
<% Import NameSpace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
Dim dst*Products* As DataSet
dst*Products* = cache( "*Products*DS" )
If dst*Products* IS Nothing Then
dstProducts = Get*Products*( )
cache.Insert( "*Products*", dst*Products*, _
New cacheDependancy( "c:\layoutChng.txt" ) )
End If
dgrd*Products*.DataSource = dst*Products*
dgrd*Products*.DataBind( )
End SubFunction Get*Products*( ) as DataSet
Dim conNorthwind As SqlConnection
Dim strSelect As String
Dim dad*Products* As SqlDataAdapter
Dim dst*Products* As DataSet
conNorthwind = New SqlConnection( "Server=LocalHost;UID=BigAdmin;PWD=YeaRight;Database=Northwind" )
strSelect = "Select Top 20 * From *Products* Order By* ProductID*"
dad*Products* = New SqlDataAdapter( strSelect, ConNorthwind )
dst*Products* = New DataSet( )
dad*Products*.Fill( dst*Products*, " *Products*DS" )
Return dst*Products*
End Function</Script>
<HTML>
<head><title>layoutDepndsOn.aspx</title>
</head>
<body>
<asp: DataGrid ID="dgrd*Products*" Runat = "Server" />
</body>
</HTML>
或者,如果您想通过按钮点击手动控制(在家或在夜班人员的协助下)使用此方法
[基于:Steven Walther 的《ASP.NET Unleashed》(第二版),第 796-7 页]
<%@ Page %>
<Script Runat="Server">Sub UpdateItem1( s As Object, e As EventArgs )
Cache( "item1" ) = txtNewValue.Text
End Sub
Sub UpdateItem2( s As Object, e As EventArgs )
Dim arrKeyDepends() As String = { "item1" }
Cache.Insert( "item2", txtNewValue.Text, _
New CacheDependency( Nothing, arrKeyDepends ) )
End Sub</Script>
<html>
<head>
<title>基于按钮的依赖 - BBDepend.aspx</title>
</head>
<body>
<form runat="Server">
<asp:TextBox id="txtNewValue" Runat="Server" />
<p>
<asp:Button Text="更新 Item1" OnClick="UpdateItem1" Runat="Server" ></asp:Button>
<asp:Button Text="更新 Item2" OnClick="UpdateItem2" Runat="Server" ></asp:Button>
<hr />
Item1 = <%=Cache( "item1" )%>
<br />
Item2 = <%=Cache( "item2" )%>
</p>
</form>
</body>
</html>
另外,我希望上面的表格能作为快速参考。
按参数值变化:例如 <%@ outputcache duration="300" VaryByParam="none" %> | |
* |
表示每当页面使用不同的参数被请求时,都应该创建该页面的不同缓存版本 |
none |
表示在请求页面时*不*应创建该页面的不同缓存版本 |
PID |
或者基于查询字符串来根据每次请求创建不同的缓存版本。 |
按 Header 属性变化:例如 <%@ outputcache duration="300" VaryByParam="*" VaryByHeader="User-Agent" %> | |
User-Agent |
根据发起请求的浏览器来改变,以此区分不同的浏览器 |
按自定义字符串变化:例如 <%@ outputcache duration="300" VaryByParam="*" VaryByCustom="VBScript" %> - - 必须在 Global.asax 文件中创建一个函数来处理自定义字符串 - - | |
VBScript |
取决于浏览器是否支持 VBScript -- 使用 *HttpBrowserCapabilities* 类来查找主版本、是否支持 JAVA applets 等。 |
浏览器 |
页面主版本将被缓存,因此对于 IE 5.0 和 IE 5.5 将缓存相同的内容。 |
宿主 Accept - Language |
按位置变化:例如 <%@ outputcache duration="300" VaryByParam="*" Location="Client" %> - - 然而,这取决于浏览器 - - | |
任意 |
默认值。因此可以位于任何位置,包括服务器、下游服务器和浏览器。 |
客户端 |
仅在浏览器端缓存。 |
Downstream |
在服务器场部署中,在下游的任何服务器上。 |
无 |
不进行页面缓存。 |
服务器 |
仅在服务器端缓存。 |
HttpCachePolicy 类 用于更多控制 | |
SetExpires( ) |
用于设置缓存何时过期(绝对日期和时间) |
Setcacheability( ) |
用于设置页面应如何缓存。 |
Nocache |
通过 cache-Control:no-cache 头部防止缓存。 |
Private |
默认值。不能在代理服务器上缓存,但可以在浏览器上缓存。 |
Public |
页面可以在代理服务器和浏览器上缓存 |
服务器 |
仅在服务器上缓存 |
通过共享缓存页面来节省内存使用:例如 <%@ outputcache duration="300" VaryByParam="*" Shared="true" %> | |
Shared="true" |
用于在多个用户控件之间共享缓存项。 |
缓存项被移除的原因日志:原因 | |
DependencyChanged |
由于键或文件依赖而被移除。 |
Expired |
过期策略标准已满足,导致其被移除。 |
Removed |
通过显式调用 *Remove* 或 *Insert* 方法移除 |
Underused |
由于服务器资源不足而被移除。 |
我希望这能帮助您改善与各位管理员、客户的工作关系,或帮助您减少下班后的值班时间。
请务必查阅这本书,以获取更详细的信息。它物有所值,并附带大量资源。我知道它让我思考了很多,甚至给了我更多项目的想法。