Posted: April 12, 2012
IIS Site Warmup
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.
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.
AuditManager.vb
Public Class AuditManager Public Enum AuditType Exception General 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) Else _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) Next 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) _F.Write(tmpString.ToString()) _F.Close() End Using End Sub End Class
WarmUpService.vb
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...") DoTheWarmUp() AuditManager.Write(AuditManager.AuditType.General, "All Set...") End Sub Private Sub DoTheWarmUp() Try Parallel.Invoke(Sub() SetAllowUnsafeHeaderParsing20() End Sub, 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 }).ToList() 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:1.9.2.13) 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
Settings.xml
<Settings> <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="/" /> </Settings>