无需NSSM,能否将Jar文件通过java.exe作为Windows服务运行?
无需NSSM能否直接将Jar文件作为Windows服务运行?
核心结论
不能直接将Jar文件通过java.exe作为Windows服务运行,必须借助服务包装器(如NSSM、WinSW、Apache Commons Daemon)。原因是Windows服务对程序有强制的接口要求,而java.exe本身不具备与Windows服务控制器(SCM)交互的能力。
为什么你的操作会出现异常?
你用sc create指定的binPath是cmd /c java -jar ...,会触发以下问题:
- 服务进程提前退出:
cmd /c启动java.exe后,cmd.exe进程会立即退出,Windows服务控制器(SCM)检测到服务主进程退出,就会标记服务为“未运行”状态,哪怕java.exe进程还在后台运行。 - 1053错误的根源:SCM要求服务程序必须在启动后30秒内调用
StartServiceCtrlDispatcher函数,向SCM注册服务控制回调接口,以便接收启动、停止等指令。java.exe是普通控制台程序,不会执行这个操作,SCM会判定服务启动超时,抛出1053错误。 - 多实例问题:EC2的
ensureRunning配置检测到服务未运行,会反复触发服务启动,每次启动都会新建一个java.exe进程,最终导致多个实例同时运行。
Windows服务控制器与程序的交互逻辑
Windows服务管理器(SCM)和服务程序的交互必须遵循以下流程:
- SCM启动服务指定的可执行文件(即
sc create中binPath的程序)。 - 服务程序必须立即调用
StartServiceCtrlDispatcher,向SCM注册自己的服务控制回调函数。 - SCM通过回调函数向服务发送启动、停止、暂停等指令,服务程序需要响应这些指令并返回状态。
- 只有当服务程序完成启动回调并返回“运行中”状态后,SCM才会标记服务为运行状态。
普通程序(如java.exe、cmd.exe)不会执行步骤2的操作,因此无法被SCM识别为合法的服务。
针对AWS CloudFormation部署的可行方案
既然无法绕过包装器,推荐以下适合自动化部署的方案:
方案1:使用NSSM(轻量化推荐)
NSSM是开源服务包装器,可以将任意程序包装成Windows服务,支持路径空格、自动重启等需求。在CloudFormation的init脚本中可按以下步骤操作:
- 通过PowerShell下载NSSM到实例:
Invoke-WebRequest -Uri "https://nssm.cc/release/nssm-2.24.zip" -OutFile "C:\Dev\nssm.zip" Expand-Archive -Path "C:\Dev\nssm.zip" -DestinationPath "C:\Dev\nssm"
- 用NSSM创建并配置服务:
C:\Dev\nssm\win64\nssm install IncrementServer "C:\Dev\Java\jdk-11.0.7\bin\java.exe" C:\Dev\nssm\win64\nssm set IncrementServer AppParameters "-jar C:\Dev\IncrementAndLog.jar" C:\Dev\nssm\win64\nssm set IncrementServer Start SERVICE_AUTO_START C:\Dev\nssm\win64\nssm set IncrementServer AppDirectory "C:\Dev"
- 启动服务:
C:\Dev\nssm\win64\nssm start IncrementServer
方案2:使用WinSW(开源可自定义)
WinSW是.NET编写的服务包装器,支持XML配置文件,适合复杂场景:
- 下载WinSW的exe文件,重命名为
IncrementServer.exe,并创建对应配置文件IncrementServer.xml:
<service> <id>IncrementServer</id> <name>IncrementServer</name> <description>Jar应用服务</description> <executable>C:\Dev\Java\jdk-11.0.7\bin\java.exe</executable> <arguments>-jar C:\Dev\IncrementAndLog.jar</arguments> <startmode>Automatic</startmode> <logpath>C:\Dev\logs</logpath> </service>
- 在CloudFormation脚本中执行服务安装与启动:
C:\Dev\IncrementServer.exe install C:\Dev\IncrementServer.exe start
总结
Windows服务的运行依赖特定系统接口,普通Java程序(通过java.exe启动)无法直接满足要求,必须借助服务包装器实现与SCM的交互。对于AWS CloudFormation自动化部署场景,NSSM或WinSW都是成熟的选择,能可靠实现Jar应用的开机自启和持续运行。
内容的提问来源于stack exchange,提问作者Steveit
相关产品推荐
相关产品推荐

