Fil cache i ASP

Tags:    asp
Skrevet af Bruger #2193 @ 13.10.2002
Optimering med brug af fil til cache.


Introduktion:

Her vil vi se på hvordan vi kan optimere ved at gemme data vi ellers henter fra ekstern side (et andet site) i en fil på vores egen server, lige som vi har set i en artikel i PHP/mySQL. Koden er ikke fuldkommen men blot brud af den fuldstændige kode. Der skulle dog gerne være nok til at se kernen, og hele koden ville forvirre mere end det ville gavne.

Funktionaliteten:

Vi har en eller anden function der henter data fra et eksternt site, og jeg har valgt at tage et eksempel der henter nyheder fra et andet site og formaterer dem om. Dette er taget fra et virkeligt site jeg skulle lave noget optimering på, og asp siden der importere nyheder blev inkluderet i en frame på forsiden, dvs den blev kørt hver eneste gang en besøgende kom på forsiden og det tog omkring 120 til 160 millisekunder af køre koden.

Nyheds koden:

 1	<%
 2 	set HttpReq = server.CreateObject("WinHttp.WinHttpRequest.5")
 3 	HttpReq.open "GET", sUrl, False
 4 	HttpReq.send
 5 
 6 	strText=HttpReq.responseText
 7 
 8 
 9 	fields=split(strText,"|")
10 	maxcounter=ubound(fields)
11 
12 	pos=0
13 	while (pos < maxcounter)
14 
15 		Response.Write "	  <tr>"
16 		Response.Write "		<td>"
17 		Response.Write "		  <br>"
18 		Response.Write "		  <div class='startxt'>" &
 fields(pos+1) & " fortæller...</div>"
19 		Response.Write "		  <div 
class='startmillihead'>" & fields(pos+2) & "</div><br>"
20 
21 		if (fields(pos+5)<>"") then
22 			Response.Write "		
	<div class='startxt'><img border='0' src='" & fields(pos+5) & "' 
alt='' align='right' border='1'>" & fields(pos+3) & "<br><br>"
23 		else
24 			Response.Write "		
	<div class='startxt'>" & fields(pos+3) & " <br> <br>"
25 		end if
26 
27 		Response.Write "		  [ <a href='" & fields
(pos+4) & "' target='_blank'>Mere</a> ]</div><br><br>"
28 		Response.Write "		  </td>"
29 		Response.Write "		</tr>"
30 		Response.Write "	   <tr>"
31 		Response.Write "		<td><hr size='1'></td>"
32 		Response.Write "	  </tr>"
33 
34 		pos = pos + 6
35 	wend
36 
37 	set HttpReq = nothing
38 	%>
Linie 2-6: Skab et HttpRequest object, åben siden som er i url'en sUrl og hent siden ind i strText.
Linie 9-10: Split data op i et Array med split, og tæl antal felter i vores Array.
Linie 13: Start Loop igennem vores Array.
Linie 15-32: Formater aktuelle nyhed.
Linie 34: Øg vores position i loopet.
Linie 35: Slut Loop.
Linie 37: Ryd op efter vores HttpRequest object.

Som sagt tog dette omkring 120 til 160 millisekunder, og det lyder måske ikke af så meget, men har du mange hits så er det for meget på en forside, og nyhederne var blot en del af forsiden.
Desuden er det jo lidt kedeligt hele tiden at henmte nyhederne når de måske bare ændres en enkelt gang i døgnet, eller måske hver anden time.

Nyheds kode med cache fil:

Løsningen er, ligesom i PHP eksemplet, at skrive data i en fil på vores server, og starte med at skrive tiden i filen så vi kan checke om det er tid til at opdatere vores fil.
Så kan man jo justere om filen skal opdateres en gang i minuttet, timen, døgnet eller hvad ved jeg.

Her kommer den så ... hold fast eller løb lidt ned til kommentarerne.
1  <%
2  dim strText
3  Dim HttpReq
4  Dim pos
5  Dim maxcounter
6  dim objMail
7  public fields
8  Dim cacheFile
9  Dim objFSO
10 Dim objTSream
11 Dim maxCacheAgeMin
12 Dim reloadCache
13 maxCacheAgeMin = 60
14 reloadCache = False
15 
16 cacheFile = "c:\\fd_start.txt"
17 Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
18 
19 if objFSO.FileExists(cacheFile)  then
20 
21 	Set objTStream = objFSO.OpenTextFile(cacheFile)
22 	cacheDate = objTStream.read(19)
23 	if now > DateAdd("n",maxCacheAgeMin,cacheDate) then
24 
25 		%>Cache too old!<br><%
26 		reloadCache = True
27 		objTStream.Close
28 
29 	end if
30 else
31 
32 	reloadCache = True
33 
34 end if
35 
36 if reloadCache then
37 
38 	Set objTStream = objFSO.CreateTextFile(cacheFile,True)
39 	objTStream.write right("00" & month(Now),2) & "/" & 
right("00" & day(Now),2) & "/" & year(now) & " " & 
right("00" & hour(Now),2) & ":" & right("00" & minute(Now),2) & 
":" & right("00" & second(Now),2)
40 
41 
42 	set HttpReq = server.CreateObject("WinHttp.WinHttpRequest.5")
43 	HttpReq.open "GET", sUrl, False
44 	HttpReq.send
45 
46 	strText=HttpReq.responseText
47 
48 
49 	fields=split(strText,"|")
50 	maxcounter=ubound(fields)
51 
52 	pos=0
53 	while (pos < maxcounter)
54 
55 		objTStream.writeline "	  <tr>"
56 		objTStream.writeline "		<td>"
57 		objTStream.writeline "		  <br>"
58 		objTStream.writeline "		  <div 
class='startxt'>" & fields(pos+1) & " fortæller...</div>"
59 		objTStream.writeline "		  <div 
class='startmillihead'>" & fields(pos+2) & "</div><br>"
60 
61 		if (fields(pos+5)<>"") then
62 			objTStream.writeline "		
	<div class='startxt'><img border='0' src='" & fields(pos+5) & "' 
alt='' align='right' border='1'>" & fields(pos+3) & "<br><br>"
63 		else
64 			objTStream.writeline "		
	<div class='startxt'>" & fields(pos+3) & " <br> <br>"
65 		end if
66 
67 		objTStream.writeline "		  [ <a href='" 
& fields(pos+4) & "' target='_blank'>Mere</a> ]</div><br><br>"
68 		objTStream.writeline "		  </td>"
69 		objTStream.writeline "		</tr>"
70 		objTStream.writeline "	   <tr>"
71 		objTStream.writeline "		<td><hr size='1'></td>"
72 		objTStream.writeline "	  </tr>"
73 
74 		pos = pos + 6
75 	wend
76 
77 	set HttpReq = nothing
78 
79 
80 	objTStream.Close
81 	%>Cache reloaded!<br><%
82 	Set objTStream = objFSO.OpenTextFile(cacheFile)
83 	cacheDate = objTStream.read(19)
84 
85 
86 end if
87 
88 Response.Write(objTStream.readAll)
89 objTStream.Close
90 
91 set objTStream = nothing
92 set objFSO = nothing
93 %>
Linie 2-12: Noget trivielt Dim.
Linie 13: Vi sætter vores maxCacheAgeMin til 60, og det betyder at vores cache max må være 60 minutter gammel.
Linie 16: Vores cache fil bestemmes.
Linie 19-34: Hvis vores cache fil eksisterer og er for gammel eller ikke eksisterer, så markerer vi at vi skal genindlæse vores data.
Linie 36-39: Skal vi genindlæse, så overskriver vi cache filen og skriver tid og dato fra Now i filen.
Linie 42-77: Her sker det samme som før, bortset fra at nu bruger vi "objTStream.writeline", istedet for "Response.Write", og det gør at vi skriver til vores fil istedet for til browseren.
Linie 80-83: Så lukker vi filen i skrive mode, og åbner den i læse mode og læser forbi tid og dato mærket.
Linie 88: Her læser vi retsen af filen op og sender til browseren.

Betaler det sig?

Ja helt klart.
Eksekveringstiden på denne version var under 10 millisekunder.
"Hvad så" tænker du måske, og 100 millisekunder fra eller til ser måske ikke så stort ud.
Måske ikke, men "mange bække små" som du jo nok husker, og endelig skal du vide at performance bliver bedre end bare tidsforskellen for vi sparer serveren for meget load eftersom vi sætter cpu ned i vores script.
Vi gemmer jo endda formateringen i filen, så vi skal ikke engang formatere data, bare læse dem op fra vores cache fil.
"Hvad så når cachen skal indlæses igen, så tager det jo tid ikke?"
Jo, det gør det, men nu har vi en situation hvor det ikke sker så ofte, en enkelt gang i timen, istedet for en hvor det sker i hvert eneste forside besøg.



Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (0)

Du skal være logget ind for at skrive en kommentar.
t