Windows 伺服器

Windows 伺服器程式 24 小時掛機:任務計劃程式開機自啟、NSSM 註冊為服務與崩潰自動重啟

5 個步驟 8 分鐘閱讀 26 次閱讀 0
本文目錄

從遠端桌面會話中啟動的程式,會在該會話登出時停止,伺服器重啟後也不會自動恢復。機器人、遊戲伺服器、Node.js 或 Python 應用、資料採集程式和交易工具等,應該隨 Windows 自動啟動,並在崩潰後自動重啟。本文介紹在 Windows Server 上實現這一目標的三種可靠方法:任務計劃程式、免費的服務封裝工具 NSSM,以及 Windows 自帶的服務恢復設定。

直接關閉遠端桌面視窗(斷開連線)時程式會繼續執行,但選擇登出(Sign out)、觸發會話自動超時或伺服器重啟都會關閉程式。凡是需要 7×24 小時執行的程式,都不要依賴一直開著的遠端桌面會話。

應該選擇哪種方法?

方法適用場景崩潰後自動重啟需要保持桌面登入
任務計劃程式“啟動時”觸發指令碼和控制臺程式是(通過重試設定)否
NSSM 服務長期執行的控制臺程式(Node.js、Python、Java、遊戲伺服器)是,立即重啟否
自動登入 + 啟動資料夾需要顯示視窗或圖形介面的程式否是

方法 1:任務計劃程式開機啟動

開啟 taskschd.msc,選擇建立任務(Create Task)(不要選“建立基本任務”):

  1. 常規(General):選擇不管使用者是否登入都要執行(Run whether user is logged on or not)和使用最高許可權執行(Run with highest privileges)。
  2. 觸發器(Triggers):新建 → 啟動時(At startup);可以勾選延遲任務時間(Delay task for)並設為 30 秒,等網路就緒後再啟動。
  3. 操作(Actions):啟動程式,填寫程式或指令碼的完整路徑,並在起始於(Start in)中填寫其所在資料夾。
  4. 設定(Settings):勾選如果任務失敗,按以下頻率重新啟動(If the task fails, restart every),設為 1 分鐘,最多重試 999 次;對於長期執行的程式,請取消勾選如果任務執行時間超過以下時間,停止任務(Stop the task if it runs longer than)。

也可以用 PowerShell 建立同樣的任務:

$action   = New-ScheduledTaskAction -Execute "C:\apps\collector\collector.exe" -WorkingDirectory "C:\apps\collector"
$trigger  = New-ScheduledTaskTrigger -AtStartup
$trigger.Delay = "PT30S"
$settings = New-ScheduledTaskSettingsSet -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) `
            -ExecutionTimeLimit ([TimeSpan]::Zero) -StartWhenAvailable
Register-ScheduledTask -TaskName "Collector" -Action $action -Trigger $trigger -Settings $settings `
            -User "SYSTEM" -RunLevel Highest

Start-ScheduledTask -TaskName "Collector"
Get-ScheduledTaskInfo -TaskName "Collector"   # LastTaskResult 0 = success

方法 2:用 NSSM 將任意程式註冊為服務

NSSM(Non-Sucking Service Manager)可以把任意執行檔封裝成真正的 Windows 服務,程式退出時會立即將其重啟,並能把控制臺輸出寫入日誌檔案。從 nssm.cc 下載後,將 nssm.exe(位於 win64 資料夾中)複製到 C:\Windows\System32,然後執行:

# Example: a Node.js application
nssm install MyApp "C:\Program Files\nodejs\node.exe" "C:\apps\myapp\server.js"
nssm set MyApp AppDirectory C:\apps\myapp
nssm set MyApp AppStdout C:\apps\myapp\logs\out.log
nssm set MyApp AppStderr C:\apps\myapp\logs\error.log
nssm set MyApp AppRotateFiles 1
nssm set MyApp AppRotateBytes 10485760
nssm set MyApp Start SERVICE_AUTO_START
nssm start MyApp

nssm status MyApp
nssm restart MyApp
nssm edit MyApp       # graphical editor for all settings
nssm remove MyApp confirm

Python 指令碼請使用 python.exe 的路徑,並把指令碼作為引數;Java 程式請使用 java.exe 並加上引數 -jar app.jar。如果程式需要訪問網路共享或使用者配置檔案,請在 Log on 選項卡(通過 nssm edit 開啟)中指定執行帳戶,而不是使用 LocalSystem。

方法 3:為現有服務配置恢復選項

如果程式本身已經安裝為服務(例如資料庫、遊戲伺服器或監控代理),可以讓 Windows 在其故障時自動重啟:

# Restart after 5 seconds on the first three failures; reset the failure counter after one day
sc.exe failure "MyService" reset= 86400 actions= restart/5000/restart/5000/restart/5000
sc.exe failureflag "MyService" 1
sc.exe config "MyService" start= auto
sc.exe qfailure "MyService"

這些選項也可以在服務屬性的恢復(Recovery)選項卡中設定(開啟 services.msc 後雙擊該服務)。

需要顯示桌面視窗的程式

服務執行在一個隔離的會話中,沒有可見的桌面,因此必須顯示視窗的圖形介面程式(如部分交易終端、遊戲客戶端、自動化工具)無法以服務方式執行。對於這類程式,可以使用 Microsoft Sysinternals 的 Autologon 工具為一個專用使用者啟用自動登入(密碼會加密儲存),把程式的快捷方式放入該使用者的 shell:startup 資料夾,離開遠端桌面時選擇斷開連線而不是登出。同時,請將該使用者排除在會話自動登出的時間限制之外。

常見問題

任務狀態顯示“正在執行”,但程式並沒有正常工作?

檢查是否設定了起始於(Start in)(或 NSSM 的 AppDirectory):很多程式會按工作目錄的相對路徑查詢配置檔案。同時檢視程式自身的日誌;如果使用 NSSM,還要檢視 AppStderr 指定的日誌檔案。

服務啟動後立即停止?

在 PowerShell 視窗中手動執行完全相同的命令,檢視報錯資訊。對於服務,還可以檢視事件檢視器 → Windows 日誌 → 系統(Event Viewer → Windows Logs → System)和應用程式(Application)日誌。

Windows 更新重啟後程式還會自動執行嗎?

會。開機啟動任務和自動啟動的服務在每次重啟後都會再次啟動,這正是它們比一直開著遠端桌面會話更可靠的原因。如需控制重啟時間,請參見管理 Windows 更新。

如果按以上步驟操作後問題仍未解決,請提交工單聯絡 IMIDC 7×24 技術支援,並附上伺服器 IP、Windows Server 版本、需要執行的程式,以及具體的報錯資訊或事件日誌記錄,方便工程師快速定位。

這篇文章有幫助嗎?

相關教程