Wednesday, April 29, 2015

Keeping your Azure Website warm and up to speed

So, you have deployed a web app to an Azure Website. As one might expect, the first web site request is slow, it might take 10 seconds  or maybe even more to respond. It is because the web site is unloaded(cold) and it has to load in(warm up). This first request loads the site, and when it is loaded, it responses quite fast(depending on our code).

But after a period(around 30 minutes) with idle traffic, your web site unloads again. And again to get it loaded again, it needs an request. And again it takes time to load it.

In the Basic and Standard plans for Azure websites, you can disable this feature by setting the Always On option. That was a quick fix :-). If you are using Free or Shared Azure Websites, you can consider following strategies:
  1. Do nothing, if you can live with it. Also If/When your site is frequently visited, it is not an problem. It is only websites with low traffic, such as new sites, suffers from this issue.
  2. Use one of these 'Ping my add' services on the web to request your site. I'm quite sure, this is a solution you should avoid.
  3. Find/own/borrow/invent a machine which is on 24/7 and setup a job to make a request to your site every 5-10 minute.
  4. Keep it all in Azure, Create an Azure Webjob to make a request to your site every 5-10 minute.

I'll explain solution 4, it might have some cons regarding pricing, but I'll cover that.

Azure WebJobs

Azure WebJobs can handle following extensions:

.cmd, .bat, .exe, .ps1, .sh, .php, .py, .js, .jar

I'll show an example, with C# where we are making a console .exe file. The Azure WebJob code:

 using System.Net;  
 namespace HeartBeat  
 {  
   class Program  
   {  
     static void Main(string[] args)  
     {  
       var WebReq = (HttpWebRequest)WebRequest.Create(string.Format("http://<your site>/special_ping_endpoint"));  
       WebReq.Method = "GET";  
       WebReq.GetResponse();  
     }  
   }  
 }  

Now, this is important. Do not ping your landing page, eg. www.example.com, it might cost more resources, specially if you landing page makes web call and database lookups behind the scenes. It might be noticeable on your Azure bill. Create a special minimal endpoint for the purpose, and make it return empty.

An example of such endpoint in

ASP.NET MVC 5 and prior
 using System.Web.Mvc;  
 namespace ActionHandlers.Controllers  
 {  
   public class PingController : Controller  
   {  
     public ActionResult Get()  
     {  
       return new EmptyResult();  
     }  
   }  
 }  


Or ASP.NET 5 MVC 6
 using Microsoft.AspNet.Mvc;  
 namespace ActionHandlers.Controllers  
 {  
   public class ExampleController : Controller  
   {  
     public IActionResult Get()  
     {  
       return new EmptyResult();  
     }  
   }  
 }  


Azure WebJob considerations regarding costs

The WebJob is the thing which properly is going to cost you, but it depends. Azure WebJobs is dependent of Azure Scheduler, and Azure Scheduler comes in 3 plans: Free, Standard and Premium. The biggest difference regarding to our case, is how frequent a job can run. With the free plan, a job can run once in an hour, while for Stardard and Premium, they can run once in a minute.

So with a newly created web site, it would be optimal with the standard plan and ping every 5-10 minute, for keeping your site warm. But it is a bit pricy. But you could use the free plan and do a ping every hour and hoping to have a visit after 15-30 minuttes after the ping, then your site is properly warm until next ping. You could consider following strategies, for keeping your site warm.
  1. Completely new and fresh website: Traffic is going to be very light, use the standard plan
  2. Website with light traffic: Use the free plan
  3. Website with often traffic: No plan.
Using Free or Shared Websites with a Azure Scheduler, it still cheaper than switching to Basic Websites and use Always On. Also, using a scheduler should only be a temporary solution, until you site has good traffic. 

Alternative WebJob way

Making an Azure WebJob, with a thread sleep for 5-10 minuttes and run it continuously without a scheduler, is not a recommendable solution. Because Azure is able to unload websites with associated unscheduled WebJobs.

WebJob Installation

Put you WebJob code into a zip, in our case it will be the compiled exe and config file, from either the Debug or Release folder in your Visual Studio Project (I'll take the liberty to assume, your using Visual Studio).

Go to the Dashboard for you Website, and find the WebJob tab. Add the WebJob.

1 comment:

  1. Unfortunately solution 4 doesn't work anymore. This is the log of my warm up web job:
    [04/11/2016 15:03:40 > 47bb4f: SYS INFO] WebJob is stopping due to website shutting down
    [04/11/2016 15:03:40 > 47bb4f: SYS INFO] Status changed to Stopping
    [04/11/2016 16:54:36 > 47bb4f: SYS INFO] Status changed to Starting
    [04/11/2016 16:54:36 > 47bb4f: SYS WARN] 'Always On' doesn't appear to be enabled for this Web App. To ensure your continuous job doesn't stop running when the SCM host is idle for too long, consider enabling 'Always On' in the configuration settings for your Web App. Note: 'Always On' is available only in Basic, Standard and Premium modes.

    Now web job is shut down together with the app.

    ReplyDelete