Windows NT 服務(現稱 Windows Service)是無用戶界面、隨系統啟動、以特定賬號(如 LocalSystem)運行、由 SCM (Service Control Manager) 管理的長生命周期進程。類似 Unix/Linux 的 Daemon。典型例子:SQL Server、IIS、Print Spooler。
標準 Java SE 無原生 API 操作 SCM。歷史方案:
service.zip 類庫、jntsvc.exe 打包工具)。service.zip 解壓至 %JAVA_HOME%\jre\lib\ext(擴展類加載路徑)。jntsvc.exe 目錄加入 PATH。import com.ms.service.Service;
import com.ms.service.ServiceControl;
public class EchoSvc extends Service {
private Thread workerThread;
private volatile boolean running = false;
@Override
public void startService() {
running = true;
workerThread = new Thread(() -> {
while (running) {
// 業務邏輯:Socket 監聽、定時任務等
try { Thread.sleep(5000); } catch (InterruptedException ignored) {}
}
});
workerThread.start();
}
@Override
public void stopService() {
running = false;
workerThread.interrupt();
try { workerThread.join(5000); } catch (InterruptedException ignored) {}
}
public static void main(String[] args) {
// 僅供測試,實際由 SCM 調用
EchoSvc svc = new EchoSvc();
svc.startService();
}
}
javac EchoSvc.java
jntsvc *.class /OUT:EchoSvc.exe /SVCMAIN:EchoSvc "/SERVICENAME:EchoSvc"
/OUT:生成可執行文件名。/SVCMAIN:包含 startService/stopService 的入口類。/SERVICENAME:註冊表服務名。EchoSvc.exe -install // 註冊到 SCM
net start EchoSvc // 啟動
net stop EchoSvc // 停止
EchoSvc.exe -uninstall // 卸載
強烈建議新項目使用此方案,支持 JDK 8/11/17/21,開源、活躍維護。
<dependency>
<groupId>commons-daemon</groupId>
<artifactId>commons-daemon</artifactId>
<version>1.3.4</version>
</dependency>
org.apache.commons.daemon.Daemon
public class MyService implements Daemon {
private Thread worker;
private volatile boolean running = false;
@Override
public void init(DaemonContext context) throws Exception {
// 解析命令行參數、加載配置
}
@Override
public void start() throws Exception {
running = true;
worker = new Thread(this::runLoop);
worker.start();
}
@Override
public void stop() throws Exception {
running = false;
worker.interrupt();
worker.join(10000);
}
@Override
public void destroy() {
// 清理資源
}
private void runLoop() {
while (running) { /* 業務邏輯 */ }
}
}
prunsrv.exe //IS//MyService \
--DisplayName="My Java Service" \
--Install="C:\path\prunsrv.exe" \
--Jvm=auto \
--Classpath="C:\app\lib\*;C:\app\my-service.jar" \
--StartMode=jvm --StartClass=com.app.MyService --StartMethod=start \
--StopMode=jvm --StopClass=com.app.MyService --StopMethod=stop \
--LogPath="C:\app\logs" --StdOutput=auto --StdError=auto \
--User=DOMAIN\svc_account --Password=***
stop()/destroy() 釋放端口、關閉連接池、刷新緩存。:8080/health)供監控系統探活。-Xms -Xmx -XX:+UseG1GC -XX:MaxMetaspaceSize 等通過 --JvmOptions 傳遞。Java 編寫 Windows 服務的核心是將 JVM 進程包裝為 SCM 可識別的原生進程。歷史上 Microsoft SDK 提供了原生類庫但已淘汰;現代標準方案是 Apache Commons Daemon (Procrun) 或 winsw,配合 Daemon 接口實現生命周期管理。掌握服務安裝、日誌、優雅關閉、權限控制等工程化細節,才能構建生產級穩定的 Windows 後台服務。