Achtergrond verwerking voor websites met Task Scheduler

17 sep. 2017

Veel websites voeren verwerkingen uit die niet noodzakelijk door de website zelf uitgevoerd hoeven te worden. Zaken als het versturen van emails of het verwerken van orders hoeven vaak niet naar de website terug te koppelen dat ze gereed zijn. In dit soort situaties kan het werk beter gedaan worden door een proces buiten de context van de website. Dit maakt meer bronnen vrij voor het verwerken van echte gebruikers acties, waardoor de website potentieel sneller zal reageren. De website code wordt zo ook schoner en simpeler.

Voorbeelden

  • Elke paar minuten emails versturen voor gedane bestellingen
  • Achtergrond verwerking van orders
  • Opschonen van database records

Implementatie kiezen

Er zijn veel manieren om achtergrond taken te bouwen en te gebruiken. Vooral in Cloud omgevingen zijn er veel opties. Azure heeft bijvoorbeeld onder andere Webjobs en het nieuwere Functions. Deze Cloud oplossingen zijn in veel gevallen de beste keuze omdat ze makkelijk in gebruik zijn, snel op te zetten en veel mogelijkheden bieden. Maar niet iedereen kan of wil zijn code in de Cloud draaien. Als je niet voor Cloud gaat maar voor een on-premise oplossing dan is vaak de eerste keuze om een Windows Service te bouwen om je achtergrond werk in uit voeren. Een andere optie is echter een console app bouwen en deze door de Windows Task Scheduler laten uitvoeren. Een console app is meestal makkelijk te testen en eenvoudiger te deployen dan een Windows Service. De console app kan vervolgens bijvoorbeeld elke 5 minuten gestart worden door de Task Scheduler om emails te versturen naar alle klanten die iets besteld hebben in je webshop in de afgelopen 5 minuten. Door de Task Scheduler te gebruiken hoef je niet zelf code te schrijven om je achtergrond taak periodiek uit te voeren. Task Scheduler heeft ook een eigen retry mechanisme, ook iets wat je dus niet zelf hoeft te bouwen. In de meeste gevallen waar je achtergrond werk periodiek wil uitvoeren is de combinatie van console app en Task Scheduler daarom de beste keuze. Hieronder de voor en nadelen van Windows Services en console app's met Task Scheduler op een rijtje.

Windows Service

Voorbeelden

  • Een service die wacht op inkomende berichten van een andere service
  • Een taak die de status van een gerelateerd systeem controleert met hele korte tussenposes (< 1 minuut)

Voordelen

  • Is altijd actief dus kan bijvoorbeeld wachten op binnenkomende berichten
  • Draait in een afgeschermde/veilige context

Nadelen

  • Is altijd actief dus gebruikt altijd systeem bronnen
  • Als je werk heb dat periodiek uitgevoerd moet worden, dan moet je hier zelf code voor schrijven
  • Lastiger om te testen
  • Relatief lastig om te deployen

Console app met Task Scheduler

Voorbeelden

  • Elke paar minuten emails versturen voor verwerkte orders
  • Elke 15 minuten de cache store verversen
  • Elke nacht een opschoon taak uitvoeren

Voordelen

  • Mogelijkheid tot uitvoeren van periodieke taken is inbegrepen
  • Is alleen actief wanneer gewenst dus gebruikt ook alleen dan systeem bronnen
  • Heel makkelijk te testen
  • Gemakkelijk te deployen

Nadelen

  • Niet geschikt voor taken die altijd actief moeten zijn
  • Alle gebruikers met toegang tot de server kunnen de taak uitvoeren

Deployment van Console app en Task Scheduler

Deployment van de console app is zo eenvoudig als het kopiƫren van de juiste bestanden (.exe, .dll en .config). De meeste deployment tools hebben hier gemakkelijke standaard opties voor. Het instellen van de Task Scheduler kan uiteraard met de hand via de Graphic User Interface van de Task Scheduler. Maar je kan dit ook automatiseren met behulp van PowerShell Scripts. Je deployment tool kan deze scripts dan uitvoeren zodat de volledige deployment met een druk op de knop uitgevoerd kan worden.

Powershell script voor aanmaken van een Task Scheduler taak
    $name = "My Task"
    $user = "####"
    $installRoot = "c:\windows"

    Unregister-ScheduledTask -TaskName $name -ErrorAction SilentlyContinue -Confirm:$false	
    $action = New-ScheduledTaskAction -Execute $installRoot"\notepad.exe"
    $settings = New-ScheduledTaskSettingsSet -MultipleInstances IgnoreNew
    $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).Date -RepetitionInterval (New-TimeSpan -Minutes 5)
    Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $name -Description "Task to do something usefull" -Settings $settings -User $user

Met dit voorbeeld script worden eerst een paar variabelen gezet. Daarna wordt eerst de Scheduled Task verwijderd als deze al bestaat, dit is gemakkelijker dan eerst controleren of de Task als bestaat en zo ja de bestaande taak aanpassen. Vervolgens wordt een actie samengesteld welke moet worden uitgevoerd door de taak (in dit voorbeeld het openen van Kladblok). Dan worden wat instellingen gezet, als voorbeeld wordt hier ingesteld dat de Task niet opnieuw uitgevoerd mag worden als de vorige nog bezig is. Daarna wordt het schema (trigger) bepaald wanneer de Task uitgevoerd moet worden. In dit voorbeeld wordt gestart op de huidige datum waarna de Task elke 5 minuten herhaald wordt. Een ander simpeler voorbeeld van een trigger zou kunnen zijn $trigger = New-ScheduledTaskTrigger -Daily -At 6am (elke dag om 6 uur in de ochtend). Tenslotte wordt alles samengevoegd en wordt de Task geregistreerd. In de meeste gevallen kan de Task het beste draaien onder de NETWORK SERVICE of LOCAL SERVICE accounts. Als je een normale gebruikersaccount gebruikt, let dan op dat je instelt dat de Task ook moet worden uitgevoerd als de gebruiker niet is ingelogd, anders stopt de Task zodra de gebruiker uitlogt van de server waarop de Task draait. Er zijn veel meer instellingen mogelijk, klik eens door de Task Scheduler schermen in Windows of blader door de Powershell documentatie om te zien welke instellingen er zijn.

Conclusie

Kies voor on-premise achtergrond taken voor je website, web applicatie of API niet automatisch voor een Windows Service. Kijk of een simpele console app bruikbaar is in jouw geval zodat je je de overhead van een Windows Service kan besparen. In veel gevallen is dit een snellere, gemakkelijkere en efficiƫntere oplossing voor je probleem.