IIS Site Warm Up

Hey folks, 'bout time for me to come around with a little tip.

Thanks to IIS 7.5 Extensions and Microsoft (well... really Windows 8, and IIS 8 I guess...), we can now prime our Application Pools, when IIS starts.

Now, though it would be nice to be able to simply plug it in and go, unfortunately this is not the case, and there is some configuring to do.

Please see here: http://learn.iis.net/page.aspx/1089/iis-80-application-initialization/

Now, this article is not about the IIS extension, this is about priming or warming up your site.

Now, this is not a necessity, but if you are like me, you take advantage of .Net's Runtime.Caching, so simply priming your App Pools may not be enough.  My SRE (Site Rendering Engine) for one highly utilizes the server's in memory cache, as well as the Runtime.Cache, so the very first load takes a bit.

When we can prime the site itself, we can ensure that hits to it after the fact will be quick.  Thus the need for a WarmUp.

What I've done is pretty simple, yet extremely effective in doing just this.   All it does is fire up a WebClient, passes a valid User-Agent header, and pulls the site.

NOTE:  This is not limited to IIS 7.5.  It should work on any windows system, so long as it has the .Net 4 framework installed.

Here is some code for you all.  Mind you it is a VS 2010 project, so I will attach the source files as well.  Make sure to modify the Settings.xml file, just replace the url and page attributes with whatever you need to prime, you can add as many sites as you need.

It is a console application, so there are no buttons to push, there are 2 classes, and a settings file.

Public Class AuditManager

    Public Enum AuditType
    End Enum

    Public Shared Function GetPath() As String
        Return System.AppDomain.CurrentDomain.BaseDirectory()
    End Function

    Public Shared Sub Write(ByVal _Type As AuditType?, ByVal _Description As String, Optional ByVal _Location As String = Nothing, Optional ByVal _Except As Exception = Nothing)
        Dim _Stack As System.Diagnostics.StackTrace
        If _Except IsNot Nothing Then
            _Stack = New System.Diagnostics.StackTrace(_Except, True)
            _Stack = Nothing
        End If
        Using _F As New IO.StreamWriter(GetPath() & FormatDateTime(Date.Now, DateFormat.ShortDate).Replace("/", String.Empty) & ".LOG", True)
            Dim tmpString As New Text.StringBuilder
            tmpString.Append("-------------------------------------------------" & vbCrLf)
            tmpString.Append("WHEN:" & vbCrLf)
            tmpString.Append(Date.Now & vbCrLf)
            If _Type.HasValue Then
                tmpString.Append("-------------------------------------------------" & vbCrLf)
                tmpString.Append("TYPE:" & vbCrLf)
                tmpString.Append([Enum].GetName(GetType(AuditType), _Type) & vbCrLf)
            End If
            If _Location IsNot Nothing Then
                tmpString.Append("-------------------------------------------------" & vbCrLf)
                tmpString.Append("LOCATION:" & vbCrLf)
                tmpString.Append(_Location & vbCrLf)
            End If
            tmpString.Append("-------------------------------------------------" & vbCrLf)
            If _Stack IsNot Nothing Then
                tmpString.Append("STACKTRACE:" & vbCrLf)
                tmpString.Append(_Stack.ToString() & vbCrLf)
                tmpString.Append("-------------------------------------------------" & vbCrLf)
                tmpString.Append("STACK FRAMES:" & vbCrLf)
                For Each frame In _Stack.GetFrames()
                    tmpString.Append(" - FILE:" & frame.GetFileName() & vbCrLf)
                    tmpString.Append(" - METHOD:" & frame.GetMethod().Name & vbCrLf)
                    tmpString.Append(" - LINE:" & frame.GetFileLineNumber() & vbCrLf)
                    tmpString.Append(" - COLUMN:" & frame.GetFileColumnNumber() & vbCrLf)
            End If
            If _Except IsNot Nothing Then
                tmpString.Append("-------------------------------------------------" & vbCrLf)
                tmpString.Append("SOURCE:" & vbCrLf)
                tmpString.Append(_Except.Source & vbCrLf)
                tmpString.Append("-------------------------------------------------" & vbCrLf)
                tmpString.Append("MESSAGE:" & vbCrLf)
                tmpString.Append(_Except.Message & vbCrLf)
                tmpString.Append("-------------------------------------------------" & vbCrLf)
                tmpString.Append("DATA:" & vbCrLf)
                tmpString.Append(_Except.Data.ToString() & vbCrLf)
            End If
            tmpString.Append("-------------------------------------------------" & vbCrLf)
            tmpString.Append("NOTES:" & vbCrLf)
            tmpString.Append(_Description & vbCrLf)
            tmpString.Append("-------------------------------------------------" & vbCrLf)
        End Using
    End Sub

End Class

Open in new window

Imports System.Reflection
Imports System.IO
Imports System.Net
Imports System.Threading.Tasks

Module WarmUpService

    Private _SiteList As New List(Of Typing)

    Public Sub Main()
        AuditManager.Write(AuditManager.AuditType.General, "Fireing Up...")
        AuditManager.Write(AuditManager.AuditType.General, "All Set...")
    End Sub

    Private Sub DoTheWarmUp()
                            End Sub,
                                Dim _X As XElement = XElement.Load(AuditManager.GetPath() & "Settings.xml")
                                _SiteList = (From n In _X...<Site>.AsParallel()
                                            Select New Typing() With {
                                                .Page = n.@page,
                                                .Url = n.@url
                                Parallel.ForEach(_SiteList, Sub(Item)
                                                                Using _WC As New WebClient()
                                                                    _WC.Headers.Add("user-agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv: Gecko/20101203 Firefox/3.6.13")
                                                                    _WC.DownloadData(Item.Url & Item.Page)
                                                                End Using
                                                            End Sub)
                            End Sub)
        Catch ex As Exception
            AuditManager.Write(AuditManager.AuditType.Exception, "There was an issue!", "DoTheWarmUp", ex)
        End Try
    End Sub

    Private Sub SetAllowUnsafeHeaderParsing20()
        Dim a As New System.Net.Configuration.SettingsSection
        Dim aNetAssembly As System.Reflection.Assembly = Assembly.GetAssembly(a.GetType)
        Dim aSettingsType As Type = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal")
        Dim args As Object() = Nothing
        Dim anInstance As Object = aSettingsType.InvokeMember("Section", BindingFlags.Static Or BindingFlags.GetProperty Or BindingFlags.NonPublic, Nothing, Nothing, args)
        Dim aUseUnsafeHeaderParsing As FieldInfo = aSettingsType.GetField("useUnsafeHeaderParsing", BindingFlags.NonPublic Or BindingFlags.Instance)
        aUseUnsafeHeaderParsing.SetValue(anInstance, True)
    End Sub

    Partial Public Class Typing
        Public Property Url As String
        Public Property Page As String
    End Class

End Module

Open in new window

And Settings.xml
  <Site url="http://www.o7thwebdesign.com" page="/" />
  <Site url="http://www.facchinifacchinipa.com" page="/" />
  <Site url="http://skor.in" page="/" />
  <Site url="http://o7t.in" page="/" />

Open in new window

Compile it up, let it run, and warmup your sites properly.  Personally, I added a installer project, and simply added it to the server's startup so it runs everytime MS decided it needs to restart my machine for updates...

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.

Get access with a 7-day free trial.
You Belong in the World's Smartest IT Community