−25%

cho Windows trả theo năm, đến 31/10. Xem các gói

EQVPS
Bắt đầu

Cách chạy script 24/7 trên Windows Server: không chết khi đăng xuất, sự cố hay khởi động lại

Giữ bot hoặc script chạy ngày đêm trên VPS Windows Server 2022 chỉ với Task Scheduler: tự chạy khi khởi động mà không cần ai đăng nhập, tự bật lại trong vòng một phút sau sự cố và không bao giờ chạy hai bản. Chúng tôi đã tắt cưỡng bức tiến trình và khởi động lại server để kiểm tra.

Cách thường thấy để chạy bot trên VPS Windows là khởi động nó trong phiên RDP rồi đóng cửa sổ. Cách đó chạy được cho đến khi một bản cập nhật khởi động lại server lúc 3 giờ sáng và không ai bật lại bot. Task Scheduler, có sẵn trên mọi Windows Server, giải quyết việc này mà không cần phần mềm thêm. Thiết lập dưới đây:

  • chạy script khi khởi động, trước khi có ai đăng nhập;
  • bật lại nó trong vòng một phút nếu nó sập hoặc bị tắt;
  • không bao giờ chạy hai bản cùng lúc.

Chúng tôi đã thử cả ba trên image Windows Server 2022: tắt tiến trình, khởi động lại server và đếm số bản đang chạy.

Script mẫu

Một bản thay thế cho bot của bạn: cứ 10 giây ghi một dòng, nên dễ thấy nó còn sống hay không.

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

Đăng ký tác vụ

Chạy trong PowerShell có quyền quản trị:

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

Mỗi phần có tác dụng:

  • -AtStartup chạy bot khi Windows khởi động, không cần người dùng đăng nhập.
  • Lặp lại mỗi phút chạy lại tác vụ mỗi phút. Nếu bot còn sống thì không có gì xảy ra; nếu nó chết, nó khởi động lại.
  • -MultipleInstances IgnoreNew khiến việc lặp lại an toàn: lần chạy nào thấy bot đang chạy sẽ bị bỏ qua.
  • -ExecutionTimeLimit 0 tắt giới hạn mặc định 72 giờ, sau đó Task Scheduler sẽ dừng bot.
  • -User 'SYSTEM' chạy nó không cần mật khẩu hay phiên. SYSTEM có toàn quyền trên server, nên chỉ chạy mã của chính bạn theo cách này.

Với Python, thay hành động:

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

Những gì chúng tôi đã kiểm tra

Sự cố. Chúng tôi tắt tiến trình bot bằng Stop-Process -Force. 46 giây sau, trình kích hoạt mỗi phút đã chạy bản mới, và chỉ có đúng một bản.

Khởi động lại. Chúng tôi khởi động lại server và không đăng nhập. 40 giây sau khi khởi động, bot đã ghi vào nhật ký, không có phiên người dùng nào trên server.

Những gì không hiệu quả. Có hai thứ trông đúng nhưng thật ra không:

  1. "Nếu tác vụ thất bại, khởi động lại mỗi…" Chúng tôi bật nó, tắt tiến trình, và tác vụ nằm ở trạng thái Ready nhiều phút. Nó phản ứng với tác vụ không khởi động được, không phải với chương trình chết sau đó.
  2. Vòng lặp bao ngoài (while ($true) { & bot; sleep 5 }). Nó bật lại bot bị sập, nhưng nếu chính vỏ bọc chết thì tiến trình con vẫn chạy và lần khởi động kế tiếp sẽ bật bot thứ hai. Cuối cùng chúng tôi có hai bản, mà với bot Telegram nghĩa là hai tiến trình tranh nhau cùng một luồng cập nhật.

Cách kiểm tra

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

Để dừng khi bảo trì, chạy Disable-ScheduledTask mybot trước (nếu không, trình kích hoạt mỗi phút sẽ bật lại), rồi dừng tiến trình. Enable-ScheduledTask mybot đưa mọi thứ trở lại.

Nhật ký

Tác vụ không giữ lại đầu ra. Hãy để bot tự ghi nhật ký như ví dụ, hoặc chuyển hướng đầu ra trong một tệp khởi chạy .cmd nhỏ và trỏ -Execute vào tệp đó.

Chọn gói nào

Bot PowerShell hay Python dùng ít CPU, nhưng bản thân Windows chiếm từ 1 đến 1,3 GB RAM khi rảnh trên image của chúng tôi. Windows-Small (4 vCPU, 4 GB RAM, 50 GB, $11/tháng) là cỡ phù hợp cho một hai bot. Trên gói NAT, kết nối ra ngoài (Telegram, API sàn giao dịch, webhook bạn gọi) hoạt động bình thường. Nếu bot cần nhận webhook hay lưu lượng vào khác, hãy chọn Windows Small-IP ($28/tháng) có IPv4 riêng.

Bước tiếp theo: bảo mật RDP và, nếu bạn thích quản lý bot qua SSH, cài OpenSSH. Thanh toán bằng USDT, USDC hoặc ETH, và Windows là Server 2022 với giấy phép của chính bạn (BYOL). Mọi gói: Windows VPS.

FAQ

Sao không để script chạy luôn trong phiên RDP của tôi?

Cách đó chạy được cho đến khi có thứ gì kết thúc phiên: đăng xuất, khởi động lại sau cập nhật hoặc sự cố. Đóng cửa sổ RDP (ngắt kết nối) vẫn giữ phiên, nhưng đăng xuất sẽ tắt mọi thứ trong phiên, và sau khi khởi động lại thì không ai đăng nhập để chạy lại script. Tác vụ theo lịch không phụ thuộc vào phiên nào.

Task Scheduler chẳng phải có tùy chọn 'khởi động lại nếu lỗi' sao?

Có, nhưng trong thử nghiệm của chúng tôi nó không giúp gì. Khi chúng tôi tắt tiến trình của script, tác vụ chuyển sang 'Ready' và đứng yên ở đó. Tùy chọn này phản ứng khi tác vụ không khởi động được, không phải khi chương trình của bạn chết sau đó. Thứ đưa nó trở lại là trình kích hoạt lặp lại trong hướng dẫn này.

Có thể xảy ra chuyện hai bản bot của tôi cùng chạy không?

Với thiết lập này thì không. Tác vụ chạy chính bot (không có script bao ngoài) và dùng MultipleInstances IgnoreNew, nên trình kích hoạt mỗi phút không làm gì khi bot còn sống. Chính vòng lặp bao ngoài mới tạo bản trùng: tắt vỏ bọc, tiến trình con vẫn chạy, và vỏ bọc mới lại khởi động thêm một bản. Chúng tôi đã thấy đúng như vậy.

Cách này có dùng được cho Python hay Node.js không?

Có. Đặt trình thông dịch ở -Execute và script ở -Argument, với đường dẫn đầy đủ, ví dụ -Execute 'C:\Program Files\Python312\python.exe' -Argument 'C:\bots\bot.py'. Hãy cài trình thông dịch cho mọi người dùng để tài khoản SYSTEM tìm thấy nó.

Bình luận

Chưa có bình luận nào. Hãy là người đầu tiên.

Để lại bình luận

Bình luận được kiểm duyệt trước khi hiển thị.