−25%

op Windows bij jaarbetaling, tot 31/10. Naar de pakketten

EQVPS
Aan de slag

Een script 24/7 draaien op Windows Server: overleeft afmelden, crashes en herstarts

Houd een bot of script dag en nacht draaiende op een Windows Server 2022 VPS met alleen Taakplanner: start bij het opstarten zonder ingelogde gebruiker, herstart binnen een minuut na een crash en draait nooit dubbel. We hebben het proces afgeschoten en herstart om het te controleren.

Meestal start je een bot op een Windows VPS in een RDP-sessie en sluit je het venster. Dat werkt tot een update de server om 3 uur 's nachts herstart en niemand hem weer start. Taakplanner, die op elke Windows Server aanwezig is, lost dat op zonder extra software. De opzet hieronder:

  • start het script bij het opstarten, voordat iemand inlogt;
  • herstart het binnen een minuut als het crasht of wordt afgeschoten;
  • draait nooit twee kopieën tegelijk.

Alle drie hebben we getest op ons Windows Server 2022-image: proces afgeschoten, server herstart, instanties geteld.

Het voorbeeldscript

Een vervanger voor je bot: schrijft elke 10 seconden een regel, zodat je makkelijk ziet of hij leeft.

New-Item -ItemType Directory -Force C:\bots | Out-Null
Set-Content C:\bots\heartbeat.ps1 -Encoding ascii -Value @'
while ($true) {
    Add-Content -Path C:\bots\heartbeat.log -Value ("{0:u} pid {1}" -f (Get-Date), $PID)
    Start-Sleep -Seconds 10
}
'@

Registreer de taak

Voer uit in een PowerShell met beheerdersrechten:

$action   = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -ExecutionPolicy Bypass -File C:\bots\heartbeat.ps1' -WorkingDirectory 'C:\bots'
$atBoot   = New-ScheduledTaskTrigger -AtStartup
$everyMin = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 1)
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) -MultipleInstances IgnoreNew -StartWhenAvailable
Register-ScheduledTask -TaskName 'mybot' -Action $action -Trigger $atBoot, $everyMin -Settings $settings -User 'SYSTEM' -RunLevel Highest
Start-ScheduledTask -TaskName 'mybot'

Wat elk onderdeel doet:

  • -AtStartup start de bot wanneer Windows opstart, zonder ingelogde gebruiker.
  • De herhaling per minuut voert de taak elke minuut opnieuw uit. Leeft de bot, dan gebeurt er niets; is hij gestopt, dan start hij opnieuw.
  • -MultipleInstances IgnoreNew maakt de herhaling veilig: een uitvoering die de bot al draaiend aantreft, wordt overgeslagen.
  • -ExecutionTimeLimit 0 schakelt de standaardlimiet van 72 uur uit, waarna Taakplanner de bot zou stoppen.
  • -User 'SYSTEM' draait hem zonder wachtwoord of sessie. SYSTEM heeft volledige rechten op de server, dus start zo alleen je eigen code.

Voor Python vervang je de actie:

$action = New-ScheduledTaskAction -Execute 'C:\Program Files\Python312\python.exe' -Argument 'C:\bots\bot.py' -WorkingDirectory 'C:\bots'

Wat we hebben gecontroleerd

Crash. We schoten het botproces af met Stop-Process -Force. 46 seconden later had de minuuttrigger een nieuw proces gestart, en er was precies één kopie.

Herstart. We herstartten de server en logden niet in. 40 seconden na het opstarten schreef de bot al naar zijn log, zonder gebruikerssessies op de server.

Wat niet werkte. Twee dingen lijken goed en zijn het niet:

  1. 'Als de taak mislukt, opnieuw starten elke…' We zetten het aan, schoten het proces af, en de taak bleef minutenlang op Gereed staan. Het reageert op een taak die niet kan starten, niet op een programma dat later stopt.
  2. Een wrapper-lus (while ($true) { & bot; sleep 5 }). Die herstart een gecrashte bot, maar sterft de wrapper zelf, dan draait zijn kind door en start de volgende uitvoering een tweede bot. Wij eindigden met twee kopieën, wat voor een Telegram-bot betekent: twee processen die om dezelfde updates vechten.

Controleren

Get-ScheduledTask -TaskName mybot | Select-Object TaskName, State
Get-ScheduledTaskInfo -TaskName mybot | Select-Object LastRunTime, NextRunTime
Get-Content C:\bots\heartbeat.log -Tail 5

Om hem voor onderhoud te stoppen, eerst Disable-ScheduledTask mybot (anders start de minuuttrigger hem weer), dan het proces stoppen. Enable-ScheduledTask mybot brengt hem terug.

Logs

De taak vangt geen uitvoer op. Laat de bot zijn eigen log schrijven, zoals het voorbeeld, of stuur de uitvoer om in een klein .cmd-startbestand en laat -Execute daarnaar wijzen.

Welk pakket

Een PowerShell- of Python-bot gebruikt weinig CPU, maar Windows zelf neemt op ons image in rust 1 tot 1,3 GB RAM. Windows-Small (4 vCPU, 4 GB RAM, 50 GB, $11/maand) is de juiste maat voor een of twee bots. Op een NAT-pakket werken uitgaande verbindingen (Telegram, API's van beurzen, webhooks die je aanroept) gewoon. Moet de bot webhooks of ander inkomend verkeer ontvangen, kies dan Windows Small-IP ($28/maand) met eigen IPv4.

Volgende stappen: beveilig RDP en, als je de bot liever via SSH beheert, installeer OpenSSH. Betalen gaat in USDT, USDC of ETH, en Windows is Server 2022 met je eigen licentie (BYOL). Alle pakketten: Windows VPS.

FAQ

Waarom het script niet gewoon in mijn RDP-sessie laten draaien?

Dat werkt tot iets de sessie beëindigt: afmelden, een herstart na updates of een crash. Het RDP-venster sluiten (verbinding verbreken) houdt de sessie in leven, maar afmelden stopt alles daarin, en na een herstart is niemand ingelogd om het opnieuw te starten. Een geplande taak hangt van geen enkele sessie af.

Heeft Taakplanner geen optie 'opnieuw starten bij fout'?

Wel, maar in onze test hielp die niet. Toen we het scriptproces afschoten, ging de taak naar 'Gereed' en bleef daar. Die optie reageert als de taak niet kan starten, niet als je programma later stopt. Wat hem terugbrengt, is de herhalende trigger uit deze handleiding.

Kunnen er twee kopieën van mijn bot draaien?

Niet met deze opzet. De taak start de bot zelf (geen wrapper-script) en gebruikt MultipleInstances IgnoreNew, dus de minuuttrigger doet niets zolang de bot leeft. Juist een wrapper-lus maakt dubbelen: schiet je de wrapper af, dan draait zijn kindproces door en start een nieuwe wrapper er nog een. Dat zagen we precies zo gebeuren.

Werkt dit voor Python of Node.js?

Ja. Zet de interpreter in -Execute en het script in -Argument, met volledige paden, bijvoorbeeld -Execute 'C:\Program Files\Python312\python.exe' -Argument 'C:\bots\bot.py'. Installeer de interpreter voor alle gebruikers, zodat het SYSTEM-account hem vindt.

Reacties

Nog geen reacties. Wees de eerste.

Laat een reactie achter

Reacties worden gemodereerd voordat ze verschijnen.