Developments

웹사이트 퍼포먼스 향상을 위한 HTML 캐시 처리

출처 : 송준우 ( http://iendev.com http://iendev.nbloger.com )

시작하며

현재 제가 운영하는 http://nbloger.com 의 경우 개별 블로그 첫페이지의 포스트 리스트는 HTML 캐시 처리를 하고 있습니다. 가장빈번하게 요청되는 페이지이기 때문에그만큼서버상의 부담을잠재하고 있습니다. 그러나,HTML 캐시 처리 과정을 거친후방문자에게웹사이트 로딩 속도 향상 및 서버 부담을 줄이는 두가지 효과를 얻을수 있습니다.

웹서비스를 운영하면서 기능성과 더불어 가장 중요한 점검요소는 최대한의 퍼포먼스입니다. 즉, 최대한의 많은 방문자에게 빠른 속도로 보여줄수 있어야 합니다. 이점은 HTML 캐시 처리와 같은 방법으로 서버 자원의 부담을 경감시킴으로써 가능합니다.

이글에서는 HTML 캐시 처리의 기본 개념을소개하고간단한 예제를 통하여구현해보도록 하겠습니다.

클라이언트 사이드 캐시 처리

방문자가 웹사이트에 방문했을경우 웹브라우저에는클라이언트 사이드캐시 (Client side cache) 가 작동합니다. 즉, 한번 방문한 사이트일 경우 클라이언트에 HTML 및 이미지 파일등을 일시 저장해두었기 때문에 재방문시에는 그만큼 빠른 속도로 볼수 있습니다. 그러나 클라이언트 사이드 캐시의 경우 웹개발자에게는 오히려 귀찮은 존재일수 있습니다. 웹사이트의 내용을 변경 시켰음에도 불구하고,방문자에게는 예전의 모습만 보여질수 있습니다. 따라서일반적으로 서버 사이드 스크립트 (Server side script) 를 개발할 때에는 클라이언트 사이드 캐시를 강제적으로 중지 시키는 코드를 삽입합니다.



클라이언트 사이드 캐시를 중지 시킨다는 점은 그만큼 서버에게 부담을 줄수 있습니다. 캐시로 처리해도 가능한 페이지 마저 리로딩 (re-Loading) 시켜야 하기 때문에, 보통은 선별적으로 클라이언트 캐시를 중지시킵니다.

서버 사이드 캐시 처리



이글에서는 서버 사이트 캐시 (Server side cache) 를기반으로 의 부담을 줄여 퍼포먼스를 높이는 방법을 소개 드리고자 합니다. 일반적인 웹사이트의 경우 쉽게 웹서버 영역 / 어플리케이션 영역 / 데이터베이스 영역 으로 분류 됩니다. (구체적인 정보는3-tier 개발방법론 를 찾아보시기 바랍니다. ) 즉, 각 영역의 자원이 모여져 방문자에게데이터로 제공 됩니다. 그러나 방문자가 요청할때마다 매번 서버상의 자원을 동원할 필요는 사실 없습니다.

위 그림에서 붉은색 라인은 서버 사이드캐시 처리를 하지 않은 일반적인 데이터 흐름입니다. 반면 푸른색 라인은 서버 사이드 캐시 처리를 통한 데이터 흐름입니다.

서버 사이드 캐시를 구현할 경우 여러가지 방법이 있을수 있습니다. 실재로 방문자에게 전달되는 데이터의 종류에는html 파일 뿐 아니라 jpg,gif 와 같은 이미지 파일, flash 파일,ocx 그리고 그외의 바이너리 파일등이 있습니다. 이러한 데이터는 모두 캐시 처리될수 있고, 실재로 많은 솔루션들이 나와 있습니다.

HTML 캐시 처리

그러나 사실상 서버상의 자원을 가장 많이 소모하는 데이터는HTML 입니다. 예컨데 방문자와 서버간 솔루션이 캐시처리를 전혀 하지 않는다는 가정을 한다면, 방문자에게 전달될하나의 html 파일을 내부적으로 생성하기 위해서는 서버 사이드 스크립트가다른 어플리케이션 (서버 컴포넌트)을 호출하고데이터베이스가 트랜잭션을 처리해야 합니다. 만약 방문자의 요청이 많다면 서버의 부담은 더더욱 커질수 있습니다.

그러나 방문자에게 전달될 HTML 파일은 매번 다른것은 아닙니다.

블로그를 예로들때 (사실 블로그는 서버 자원을 비교적 많이 먹는 형태입니다. )포스트 리스트 및 내용을 보여주기 위해서는해당 포스트를서버 자원을 동원하여읽어와야 합니다. 그러나, 만약 블로그 관리자가 포스트를 추가 또는 편집 하지 않는다면 굳이 첫페이지를 내부적으로 매번 생성할 필요는 없습니다.따라서 빈번하게 요청되는 페이지의 경우 포스트 데이터가 변경되었을때 마다웹서버상에 HTML 캐시 파일 하나를 생성해두고 방문자에게 제공할수 있습니다.

일반적으로 HTML 캐시 처리를 할때, 전체 웹사이트에서 가장 많이 요청되는 페이지를 미리 HTML 캐시로 서버내 생성해두고 이를 방문자에게 제공할수 있습니다. 이를 통하여 서버 자원원의 부담을 줄일수 있습니다.보통 HTML 캐시 파일은 텍스트 형태 또는XML 형태로만들어 집니다.

HTML 캐시 처리의구현

HTML 캐시는 특정 HTML 페이지 전체가 될수도 있고, 부분일수도 있습니다. 또한 텍스트 형태일수도 있고, XML 형태일수도 잇습니다. 이글에서는 텍스트 파일 형태로 특정 HTML 페이지 전체를 HTML 캐시로 생성해보고자 합니다. 스크립트는 ASP 를 예로 들었습니다.






‘ ======================================================
‘ 대상 HTML 을 바이너리 형태로 읽어옵니다.
‘ ======================================================
Function GetHTMLBin(URLaddress)
Dim Http
Set Http = CreateObject(“Microsoft.XMLHTTP”)
On error resume next
Http.Open “GET”, URLaddress, False
Http.setRequestHeader “Accept-Language”,”ko”


result=Http.Send
GetHTMLBin = Http.responseBody


Set Http = Nothing
End Function



‘ ======================================================
‘ 바이너리로 읽어온것을 텍스트로 변환합니다.
‘ ======================================================
Function BinToText(varBinData, intDataSizeInBytes) ‘ as String
Const adFldLong = &H00000080
Const adVarChar = 200
Set objRS = CreateObject(“ADODB.Recordset”)
objRS.Fields.Append “txt”, adVarChar, intDataSizeInBytes, adFldLong
objRS.Open
objRS.AddNew
objRS.Fields(“txt”).AppendChunk varBinData
BinToText = objRS(“txt”).Value
objRS.Close
Set objRS = Nothing
End Function



‘ ======================================================
‘ 캐시를 생성합니다.


‘ ======================================================


Function make_chche()


Set objFile = Server.CreateObject(“Scripting.FileSystemObject”)
HTMLBin = GetHTMLBin(” http://대상 HTML 파일 주소“)
xml_body = BinToText(HTMLBin,32000)


strFname = Server.MapPath(“서버상에 저장할 캐시 파일명의 상대경로“)


if objFile.fileExists(strFname) then
objFile.DeleteFile(strFname)
end if


set out = objFile.CreateTextFile(strFname,true)
out.Write(““&chr(13)&chr(10)&xml_body)


out.close
set objFile =nothing


End Function



‘ ======================================================
‘ 캐시를읽어옵니다.


‘ ======================================================


Function read_cache()


Set objFile = Server.CreateObject(“Scripting.FileSystemObject”)
strFname = Server.MapPath(“읽어올 캐시 파일의 상대경로“)
if objFile.fileExists(strFname) then
set out = objFile.OpenTextFile(strFname,1)
str_out = out.ReadAll


out.close
else
str_out = “”
end if


read_cache = str_out


set objFile = nothing
End Function

위 소스는 XML HTTP 로 대상 HTML 을 통째로 긁어오는 형태입니다.물론 다른 방법으로 캐시 파일의 내용을 가져올수는 있습니다. 사실 위 방법은 조금 극단적(?) 일수 있습니다만 가장 간편한 방법입니다.대상HTML 이 변경될 시점마다make_cache() 함수를 실행하여서버상에 HTML 캐시를 갱신합니다. 물론 make_cache() 함수와 read_cache() 함수에 대상 HTML 파일과 생성될 HTML 캐시 파일을전달할수도 있습니다. 그리고 텍스트 파일이 아닌 XML 로HTML 캐시 파일을 생성한다면캐시에 대한 부가적인 정보를 효율적으로 한꺼번에 저장할수 있습니다.






cache_str = read_cache()


if cache_str <> “” thenresponse.write (cache_str)

대상 HTML 을 캐시처리하기 위하여위 코드를소스 상단에 추가합니다. read_cache() 함수를 통하여 미리 생성된 캐시 파일이 있는지 검사하고, 만약 있다면 캐시 파일을 읽어와 방문자에게 보여주게됩니다.

마치며

HTML 캐시 처리는 웹서버 자원의 부담을 줄이고 방문자에게 쾌적한 접근속도를 제공해줄수 있습니다.한가지 유의할점은 대상 HTML 파일이 변경되는 시점에는 반드시서버상에 HTML 캐시 파일을 갱신해줘야 합니다.그리고, 지나친 HTML 캐시처리는 개발과정에서의 효율을 떨어뜨릴수 있으므로 가장 빈번한 HTML 중심으로 적정한 수준을 지키는것이 필요합니다.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.