打造一个高性能稳定的web站点一直是站长和程序员的梦想,本文用作者的一次亲身经历的来说说如何利用xml缓存技术实现站点的高性能。我是从今年开始做138手机主题网的,采用SQL2000做为数据库,开发语言用的是Asp,查询的时候都是动态查询,直接用like %的方式,那个时候反正一天的访问量小,同时在线的时候也就几十个人而已,所以服务器也就能胜任要求,随着访问量慢慢增加,当同时在线达到几百人时,此时服务器开始不堪重负,CPU常常达到100%不降,网页打开速度也超级慢,一个查询页面需要几秒钟甚至更长,于是我开始考虑优化程序和数据库,数据库建立索引,不是很理想,因为用的是like ''% 这种方式,于是我想到了缓存,而xml本身的特点决定了他非常适合做数据库的缓存,好东西不敢独享,特发布出来,以便同行交流,共同进步。
实现的思路是这样的:程序读取信息时,先判断是否缓存了xml数据,如果有,则直接从xml中读取信息,否则从数据库中读取,并将此次结果生成xml文件,以便以后调用,加快速度,同时判断xml缓存文件是否过期,如果过期则需要重新生成xml。下面是具体的代码。
xmlcachecls.asp
<%
Rem xml数据缓存类
''--------------------------------------------------
''转载的时候请保留版权信息
''作者:walkman
''网址:手机主题 http://www.shouji138.com
''版本:ver1.0
''欢迎各位交流进步
''--------------------------------------------------
Class XmlCacheCls
Rem 私有变量定义
Private m_CacheTime ''缓存时间,单位秒
Private m_PageSize ''每页大小
Private m_CachePageNum ''xml缓存页大小
Private m_XmlFile ''xml路径,用绝对地址,不需要加扩展名
Private m_Sql ''SQL语句
Private m_TableName ''表名或者视图名
Private m_Columns ''列名 用,隔开
Private m_CurPage ''当前页
Private m_CacheType ''缓存类型:1,列表 2,详情
Private m_DataConn ''数据源,必须已经打开
Private m_QueryType ''查询类型:1,直接用sql 2,用存储过程
Private m_SQLArr ''返回的数据数组
Private m_RecordCount
Rem 公共属性
''缓存时间
Public Property Let CacheTime(v)
m_CacheTime = v
End Property
Public Property Get CacheTime
CacheTime = m_CacheTime
End Property
''每页大小
Public Property Let PageSize(v)
m_PageSize = v
End Property
Public Property Get PageSize
PageSize = m_PageSize
End Property
''xml缓存页大小
Public Property Let CachePageNum(v)
m_CachePageNum = v
End Property
Public Property Get CachePageNum
CachePageNum = m_CachePageNum
End Property
''xml路径,用绝对地址
Public Property Let XmlFile(v)
m_XmlFile = v
End Property
Public Property Get XmlFile
XmlFile = m_XmlFile
End Property
''xml路径,用绝对地址
''http://www.knowsky.com/article.asp?typeid=2
Public Property Let Sql(v)
m_Sql = v
End Property
Public Property Get Sql
Sql = m_Sql
End Property
''表名或者视图名
Public Property Let TableName(v)
m_TableName = v
End Property
Public Property Get TableName
TableName = m_TableName
End Property
''列名 用,隔开
Public Property Let Columns(v)
m_Columns = v
End Property
Public Property Get Columns
Columns = m_Columns
End Property
''当前页
Public Property Let CurPage(v)
m_CurPage = v
End Property
Public Property Get CurPage
CurPage = m_CurPage
End Property
''缓存类型:1,列表 2,详情
Public Property Let CacheType(v)
m_CacheType = v
End Property
Public Property Get CacheType
CacheType = m_CacheType
End Property
''缓存类型:1,列表 2,详情
Public Property Set Conn(v)
Set m_DataConn = v
End Property
Public Property Get Conn
Conn = m_DataConn
End Property
''返回记录总数
Public Property Get RecordCount
RecordCount = m_RecordCount
End Property
''返回记录数组
''http://www.devdao.com/
Public Property Get SQLArr
SQLArr = m_SQLArr
End Property
Rem 公共方法 读取数据
Public Function ReadData
If m_CacheType = 1 Then
ReadListAndSearchData
Else
ReadContentData
End If
End Function
Rem 读取详情信息
Private Function ReadContentData
Dim xmlfile
xmlfile = m_XmlFile
If FSOExistsFile(xmlfile) Then ''存在xml缓存,直接从xml中读取
ReadContentDataFromXml xmlfile
Else
ReadContentDataFromDB
End If
End Function
Rem 从xml文件读取详情信息
Private Function ReadContentDataFromXml(xmlfile)
Dim SQLARR()
Dim XmlDoc
Set XmlDoc = Server.CreateObject("msxml2.FreeThreadedDOMDocument.3.0")
XmlDoc.Load xmlfile
Dim itemslength,itemsi
itemslength = XmlDoc.documentElement.childNodes.length
For itemsi=0 To itemslength-1
ReDim Preserve SQLARR(itemslength-1,0)
SQLARR(itemsi,0) = XmlDoc.documentElement.childNodes(itemsi).text
Next
Set XmlDoc = Nothing
m_SQLArr = SQLArr
End Function
Rem 从Db中读取详情信息
Private Function ReadContentDataFromDB()
Dim rs
Dim SQLARR
Set rs = m_DataConn.execute(m_sql)
IF Not Rs.eof Then
SQLArr=Rs.GetRows(1)
rs.close
Set rs = Nothing
Else
rs.close
Set rs = Nothing
Exit Function
End If
m_SQLArr = SQLArr
End Function
Rem 读取列表数据
Private Function ReadListAndSearchData
Dim sPagesize,TotalPage,CurPage,TotalRec
sPagesize = m_PageSize * m_CachePageNum
m_CurPage = CLng(m_CurPage)
If m_CurPage Mod m_CachePageNum = 0 Then
CurPage = m_CurPage/m_CachePageNum
Else
CurPage = int(clng(m_CurPage)/m_CachePageNum)+1
End If
Dim xmlfile
xmlfile = getXmlFileName(CurPage)
If FSOExistsFile(xmlfile) Then ''存在xml缓存,直接从xml中读取
ReadListAndSearchDataFromXml xmlfile
Else
ReadListAndSearchDataFromDB
End If
End Function
Rem 从xml中读列表数据
Private Function ReadListAndSearchDataFromXml(xmlfile)
Dim SQLARR()
Dim XmlDoc
Set XmlDoc = Server.CreateObject("msxml2.FreeThreadedDOMDocument.3.0")
XmlDoc.Load xmlfile
Dim totalrecont
totalrecont = XmlDoc.documentElement.selectSingleNode("totalrec").text
m_RecordCount = totalrecont
Dim TotalRec
TotalRec = m_RecordCount
If totalrecont = 0 Then
Set XmlDoc = Nothing
m_SQLArr = SQLARR
Exit Function
End If
Dim TotalPage,curpage
curpage = m_CurPage
If m_CurPage Mod m_CachePageNum = 0 Then
CurPage = m_CurPage/m_CachePageNum
Else
CurPage = int(clng(m_CurPage)/m_CachePageNum)+1
End If
If TotalRec Mod m_CachePageNum =0 Then
TotalPage = totalrecont/m_CachePageNum
Else
TotalPage = int(clng(totalrecont)/m_CachePageNum)+1
End If
If curpage>TotalPage Then curpage=TotalPage
Dim starti
Dim startn
startn = m_curpage - (curpage-1) * m_CachePageNum
Rem 计算开始位置
starti = (startn-1) * m_pagesize
Dim items,item
Set items = XmlDoc.documentElement.SelectNodes("item")
Dim i
Dim num
Dim length
length = items.length
num = 0
For i = starti To m_PageSize + starti -1
If i >=length Then Exit For
Set item = items(i)
Dim attrlength
attrlength = item.attributes.length
ReDim Preserve SQLARR(attrlength,num)
Dim Attribute
Dim Attributei
Attributei = 0
For Attributei = 0 To attrlength-1
SQLArr(Attributei,num) = item.attributes(Attributei).Nodevalue
Next
num = num + 1
Next
Set XmlDoc = Nothing
m_SQLArr = SQLArr
End Function
Rem 从DB中读列表数据
Private Function ReadListAndSearchDataFromDB
Dim rs,Total