−25%

στα Windows με ετήσια χρέωση, έως 31/10. Δείτε τα πακέτα

EQVPS
Ξεκινήστε

Πώς να τρέχει ένα script 24/7 σε Windows Server: αντέχει αποσύνδεση, κρασαρίσματα και επανεκκινήσεις

Ένα bot ή script που τρέχει μέρα νύχτα σε VPS με Windows Server 2022 μόνο με το Χρονοδιάγραμμα εργασιών: ξεκινά στην εκκίνηση χωρίς συνδεδεμένο χρήστη, επανέρχεται μέσα σε ένα λεπτό μετά από κρασάρισμα και δεν τρέχει ποτέ σε δύο αντίγραφα. Σκοτώσαμε τη διεργασία και κάναμε επανεκκίνηση για να το ελέγξουμε.

Ο συνηθισμένος τρόπος να τρέξετε ένα bot σε Windows VPS είναι να το ξεκινήσετε σε συνεδρία RDP και να κλείσετε το παράθυρο. Δουλεύει μέχρι μια ενημέρωση να επανεκκινήσει τον server στις 3 τα ξημερώματα και κανείς να μην το ξεκινήσει ξανά. Το Χρονοδιάγραμμα εργασιών, που υπάρχει σε κάθε Windows Server, το λύνει χωρίς επιπλέον λογισμικό. Η ρύθμιση παρακάτω:

  • ξεκινά το script στην εκκίνηση, πριν συνδεθεί οποιοσδήποτε·
  • το επανεκκινεί μέσα σε ένα λεπτό αν κρασάρει ή σκοτωθεί·
  • δεν τρέχει ποτέ δύο αντίγραφα ταυτόχρονα.

Δοκιμάσαμε και τα τρία στην εικόνα μας Windows Server 2022: σκοτώσαμε τη διεργασία, κάναμε επανεκκίνηση του server και μετρήσαμε τα στιγμιότυπα.

Το παράδειγμα script

Ένα υποκατάστατο για το bot σας: γράφει μια γραμμή κάθε 10 δευτερόλεπτα, ώστε να φαίνεται εύκολα αν είναι ζωντανό.

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
}
'@

Καταχωρίστε την εργασία

Εκτελέστε σε PowerShell με δικαιώματα διαχειριστή:

$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'

Τι κάνει κάθε κομμάτι:

  • -AtStartup ξεκινά το bot όταν ξεκινούν τα Windows, χωρίς συνδεδεμένο χρήστη.
  • Η επανάληψη κάθε λεπτό ξανατρέχει την εργασία κάθε λεπτό. Αν το bot ζει, δεν συμβαίνει τίποτα· αν πέθανε, ξεκινά ξανά.
  • -MultipleInstances IgnoreNew κάνει την επανάληψη ασφαλή: μια εκτέλεση που βρίσκει το bot ήδη να τρέχει παραλείπεται.
  • -ExecutionTimeLimit 0 απενεργοποιεί το προεπιλεγμένο όριο των 72 ωρών, μετά το οποίο το Χρονοδιάγραμμα θα σταματούσε το bot.
  • -User 'SYSTEM' το τρέχει χωρίς κωδικό και χωρίς συνεδρία. Το SYSTEM έχει πλήρη δικαιώματα στον server, οπότε τρέξτε έτσι μόνο τον δικό σας κώδικα.

Για Python αλλάξτε την ενέργεια:

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

Τι ελέγξαμε

Κρασάρισμα. Σκοτώσαμε τη διεργασία του bot με Stop-Process -Force. 46 δευτερόλεπτα αργότερα ο ενεργοποιητής κάθε λεπτού είχε ξεκινήσει νέα, και υπήρχε ακριβώς ένα αντίγραφο.

Επανεκκίνηση. Κάναμε επανεκκίνηση του server και δεν συνδεθήκαμε. 40 δευτερόλεπτα μετά την εκκίνηση το bot έγραφε ήδη στο αρχείο του, χωρίς συνεδρίες χρηστών στον server.

Τι δεν δούλεψε. Δύο πράγματα μοιάζουν σωστά αλλά δεν είναι:

  1. «Αν η εργασία αποτύχει, επανεκκίνηση κάθε…» Την ενεργοποιήσαμε, σκοτώσαμε τη διεργασία, και η εργασία έμεινε λεπτά σε κατάσταση Έτοιμη. Αντιδρά σε εργασία που δεν μπορεί να ξεκινήσει, όχι σε πρόγραμμα που πεθαίνει αργότερα.
  2. Βρόχος-περιτύλιγμα (while ($true) { & bot; sleep 5 }). Επανεκκινεί ένα bot που κρασάρισε, αλλά αν πεθάνει το ίδιο το περιτύλιγμα, το παιδί συνεχίζει και η επόμενη εκκίνηση ανοίγει δεύτερο bot. Καταλήξαμε με δύο αντίγραφα, που για ένα bot Telegram σημαίνει δύο διεργασίες που τσακώνονται για τις ίδιες ενημερώσεις.

Πώς το ελέγχετε

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

Για να το σταματήσετε για συντήρηση, εκτελέστε πρώτα Disable-ScheduledTask mybot (αλλιώς ο ενεργοποιητής κάθε λεπτού το ξεκινά ξανά) και μετά σταματήστε τη διεργασία. Το Enable-ScheduledTask mybot τα επαναφέρει.

Αρχεία καταγραφής

Η εργασία δεν κρατά την έξοδο. Αφήστε το bot να γράφει το δικό του αρχείο, όπως το παράδειγμα, ή ανακατευθύνετε την έξοδο σε ένα μικρό αρχείο εκκίνησης .cmd και δείξτε το στο -Execute.

Ποιο πρόγραμμα

Ένα bot σε PowerShell ή Python χρησιμοποιεί λίγη CPU, αλλά τα ίδια τα Windows καταλαμβάνουν σε αδράνεια από 1 έως 1,3 GB RAM στην εικόνα μας. Το Windows-Small (4 vCPU, 4 GB RAM, 50 GB, $11/μήνα) είναι το σωστό μέγεθος για ένα ή δύο bots. Σε πρόγραμμα NAT οι εξερχόμενες συνδέσεις (Telegram, API ανταλλακτηρίων, webhooks που καλείτε) λειτουργούν κανονικά. Αν το bot πρέπει να δέχεται webhooks ή άλλη εισερχόμενη κίνηση, επιλέξτε το Windows Small-IP ($28/μήνα) με δικό του IPv4.

Επόμενα βήματα: προστατέψτε το RDP και, αν προτιμάτε να διαχειρίζεστε το bot μέσω SSH, εγκαταστήστε το OpenSSH. Η πληρωμή γίνεται σε USDT, USDC ή ETH, και τα Windows είναι Server 2022 με τη δική σας άδεια (BYOL). Όλα τα προγράμματα: Windows VPS.

Συχνές ερωτήσεις

Γιατί να μην αφήσω το script στη συνεδρία RDP μου;

Δουλεύει μέχρι κάτι να τερματίσει τη συνεδρία: αποσύνδεση από τον λογαριασμό, επανεκκίνηση μετά από ενημερώσεις ή κρασάρισμα. Το κλείσιμο του παραθύρου RDP (αποσύνδεση) κρατά τη συνεδρία ζωντανή, αλλά η έξοδος από τον λογαριασμό σκοτώνει ό,τι τρέχει σε αυτήν, και μετά την επανεκκίνηση κανείς δεν είναι συνδεδεμένος για να ξεκινήσει ξανά το script. Μια προγραμματισμένη εργασία δεν εξαρτάται από καμία συνεδρία.

Δεν έχει το Χρονοδιάγραμμα εργασιών ρύθμιση «επανεκκίνηση σε αποτυχία»;

Έχει, αλλά στη δοκιμή μας δεν βοήθησε. Όταν σκοτώσαμε τη διεργασία του script, η εργασία πέρασε σε «Έτοιμη» και έμεινε εκεί. Η ρύθμιση αντιδρά όταν η εργασία δεν μπορεί να ξεκινήσει, όχι όταν το πρόγραμμά σας πεθαίνει αργότερα. Αυτό που το επαναφέρει είναι ο επαναλαμβανόμενος ενεργοποιητής αυτού του οδηγού.

Μπορεί να καταλήξουν να τρέχουν δύο αντίγραφα του bot μου;

Όχι με αυτή τη ρύθμιση. Η εργασία τρέχει το ίδιο το bot (χωρίς script-περιτύλιγμα) και χρησιμοποιεί MultipleInstances IgnoreNew, οπότε ο ενεργοποιητής κάθε λεπτού δεν κάνει τίποτα όσο το bot ζει. Διπλότυπα δημιουργεί ακριβώς ένας βρόχος-περιτύλιγμα: σκοτώστε το περιτύλιγμα, η θυγατρική διεργασία συνεχίζει, και ένα νέο περιτύλιγμα ξεκινά άλλη μία. Αυτό ακριβώς είδαμε.

Λειτουργεί για Python ή Node.js;

Ναι. Βάλτε τον διερμηνέα στο -Execute και το script στο -Argument, με πλήρεις διαδρομές, για παράδειγμα -Execute 'C:\Program Files\Python312\python.exe' -Argument 'C:\bots\bot.py'. Εγκαταστήστε τον διερμηνέα για όλους τους χρήστες, ώστε να τον βρίσκει ο λογαριασμός SYSTEM.

Σχόλια

Δεν υπάρχουν ακόμη σχόλια. Γίνετε ο πρώτος.

Αφήστε ένα σχόλιο

Τα σχόλια ελέγχονται πριν εμφανιστούν.