Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I keep my Azure WebJob running without "Always On"

I have a continous webjob associated with a website and I am running that website on the Shared mode. I don't want to go to Always On option as there is no real need for my application. I only want to process the message when the calls are made to my website.

My issue is that the job keeps stopping after few minutes even though I am continuously calling a dummy keep alive method on my website at every 5 minute that posts a message to the queue that is monitored by that webjob.

My webjob is a simple console application built using the WebJob SDK that has a code like this

JobHost host = new JobHost(new JobHostConfiguration(storageConnictionSttring));
host.RunAndBlock();

and the message processing function looks like below:

public static void ProcessKeepAliveMessages([QueueTrigger("keepalive")] KeepAliveTrigger message)
{
    Console.WriteLine("Keep Alive message called on :{0}", message.MessageTime);
}

The message log for the job basically says says

[03/05/2015 18:51:02 > 4660f6: SYS INFO] WebJob is stopping due to website shutting down

I don't mind if that happen this way, but when the website starts with the next call to keep alive, the webjob is not started. All the messages are queued till I go to the management dashboard or the SCM portal as shown below

https://mysite.scm.azurewebsites.net/api/continuouswebjobs

I can see the status like this:

[{"status":"Starting","detailed_status":"4660f6 - Starting\r\n","log_url":"https://mysite.scm.azurewebsites.net/vfs/data/jobs/continuous/WebJobs/job_log.txt","name":"WebJobs","run_command":"mysite.WebJobs.exe","url":"https://mysite.scm.azurewebsites.net/api/continuouswebjobs/WebJobs","extra_info_url":"https://mysite.scm.azurewebsites.net/azurejobs/#/jobs/continuous/WebJobs","type":"continuous","error":null,"using_sdk":true,"settings":{}}]

I would really appreciate if someone can help me understand what is going wrong here.

like image 939
Kiran Avatar asked Mar 06 '15 17:03

Kiran


2 Answers

I've run into a similar problem. I have a website (shared mode) and an associated webjob (continuous type). Looking at webjob logs, I found that the job enters stopped state after about 15 min. of inactivity and stops reacting to trigger messages. It seems contradictory to the concept of continuous job concept but, apparently, to get it running truly continuously you have to subscribe to a paid website. You get what you pay for...

That said, my website needs to be used only about every few days and running in a shared mode makes perfect sense. I don't mind that the site needs a bit extra time to get started - as long as it restarts automatically. The problem with the webjob is that once stopped it won't restart by itself. So, my goal was to restart it with the website.

I have noticed that a mere look at the webjob from Azure Management Portal starts it. Following this line of thinking, I have found that fetching webjob properties is enough to switch it to the running state. The only trick is how to fetch the properties programmatically, so that restarting the website will also restart the webjob.

Because the call to fetch webjob properties must be authenticated, the first step is to go to Azure Management Portal and download the website publishing profile. In the publishing profile you can find the authentication credentials: username (usually $<website_name>) and userPWD (hash of the password). Copy them down.

Here is a function that will get webjob properties and wake it up (if not yet running):

class Program
{
    static void Main(string[] args)
    {
        string websiteName = "<website_name>";
        string webjobName = "<webjob_name>";
        string userName = "<from_publishing_profile>";
        string userPWD = "<from_publishing_profile>";
        string webjobUrl = string.Format("https://{0}.scm.azurewebsites.net/api/continuouswebjobs/{1}", websiteName, webjobName);
        var result = GetWebjobState(webjobUrl, userName, userPWD);
        Console.WriteLine(result);
        Console.ReadKey(true);
    }

    private static JObject GetWebjobState(string webjobUrl, string userName, string userPWD)
    {
        HttpClient client = new HttpClient();
        string auth = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(userName + ':' + userPWD));
        client.DefaultRequestHeaders.Add("authorization", auth);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var data = client.GetStringAsync(webjobUrl).Result;
        var result = JsonConvert.DeserializeObject(data) as JObject;
        return result;
    }
}

You can use a similar function to get all webjobs in your website (use endpoint https://<website_name>.scm.azurewebsites.net/api/webjobs). You may also look at the returned JObject to verify the actual state of the webjob and other properties.

like image 134
Andrzej Turski Avatar answered Nov 05 '22 02:11

Andrzej Turski


If you want the WebJob to not stop you need to make sure your scm site is alive.

So the keep-alive requests should go to https://sitename.scm.azurewebsites.net and these requests need to be authenticated (basic auth using your deployment credentials).

like image 41
Amit Apple Avatar answered Nov 05 '22 01:11

Amit Apple