在 Windows 环境下将自定义应用程序转换为系统服务并实现开机自启,最稳定且主流的方式是使用 WinSW (Windows Service Wrapper) 。
这种方式不需要你编写复杂的注册表脚本,且提供了良好的日志管理和自动重启机制。
1. 准备工作
下载 WinSW。
- 下载地址:WinSW GitHub Releases
2. 目录结构配置
创建一个专门的目录来存放相关文件,假设项目名为 my-app,目录结构如下:
D:\services\my-app\
├── logs (log日志文件夹)
├── my-app.jar (你的原始 JAR 包)
├── my-service.exe (将下载的 WinSW-x64.exe 改名而来)
└── my-service.xml (新建的配置文件)
注意:
.exe 文件和.xml 文件的主文件名必须完全一致,否则无法启动。下载好的服务需要改名,不能使用默认名称
WinSW-x64.exe,否则你的配置文件也必须是默认名称WinSW-x64.exe例如:
服务名称是
game-service.exe,配置文件也必须是game.service.xml
3. 编写配置文件
最简启动环境配置
使用记事本或代码编辑器打开 my-service.xml,复制并修改以下内容:
<service>
<id>my-app-service</id>
<name>My Java Application Service</name>
<description>这是一个自动启动的 SpringBoot 服务</description>
<executable>java</executable>
<arguments>-jar "D:\my-program\my-service\my-app.jar"</arguments>
<startmode>Automatic</startmode>
<log mode="roll">
<logpath>D:\my-program\my-service\logs</logpath>
</log>
</service>
3.1. 核心身份标识
这部分决定了服务在 Windows 系统中的“名字”。
-
<id> : - 含义:服务在系统内部的唯一标识符。
- 注意:不能与系统中其他服务重复(如
mysql,redis)。在命令行中使用net start [id]时,用的就是这个值。通常建议使用小写字母、数字和连字符。 -
<name> : - 含义:显示名称。
- 注意:这是你在
services.msc(服务管理器)界面中看到的名称。可以包含空格和中文。 -
<description> : - 含义:服务的详细描述。
- 注意:解释该服务的功能,方便识别,同样会显示在服务管理器描述中。
3.2. 执行与启动配置
这部分定义了“如何启动程序”。
-
<executable> : - 含义:执行程序的路径。
- 配置:
- 如果系统中配置了环境变量
JAVA_HOME,直接写java即可,由于已经定义了java路径,所以可以直接省略。 - 若未配置,需写绝对路径,如
C:\JDK21\bin\java.exe。
- 如果系统中配置了环境变量
-
<arguments> : - 含义:传递给执行程序的参数。
- 配置:对于 Java 程序,通常是
-jar "PATH_TO_JAR"。 - 你可以在这里添加 JVM 参数,例如:
-Xms256m -Xmx512m -jar "C:\app\app.jar" --server.port=8080 -
<startmode> : - 含义:启动模式。
- 选项:
-
Automatic: 开机后系统自动启动(推荐)。 -
Manual: 需手动点击启动。 -
Disabled: 禁用。
-
3.3. 日志管理策略
WinSW 会接管 Java 控制台的输出,原本启动后控制台那一串日志记录,并将其记录到文件中。
-
<log mode="roll"> : - 含义:日志滚动模式。
- 解析:
roll表示当日志文件达到一定大小时,自动切分并创建新文件。 -
<logpath> : - 含义:存放日志文件的绝对目录。
- 其他常用子标签:
-
<sizeThreshold>: 设置单个日志文件多大时切分(单位 KB,默认 10240 即 10MB)。 -
<keepFiles>: 设置保留多少个旧日志文件,超过自动替换最旧日志。
3.4. 异常处理与依赖
虽然初次配置可以省略,但在生产环境中非常重要:
-
<onfailure action="restart" delay="10 sec"/> : - 含义:当 Java 程序因为内存溢出终止或异常崩溃退出时,Windows 将在 10 秒后自动尝试重启它。
xml <onfailure action="restart" delay="10 sec"/> <onfailure action="restart" delay="30 sec"/> <onfailure action="none" />- 如果配置多个会产生梯度调度策略,可参考下方完善配置:
- 第一行 (
delay="10 sec" ) :如果是第一次崩溃,等待 10 秒重试。 - 第二行 (
delay="30 sec" ) :如果是第二次崩溃,等待 30 秒再尝试。 - 第三行 (
action="none" ) :如果是第三次及以上崩溃,停止自动重启。
- 第一行 (
-
<depend> : - 含义:服务依赖项。
- 配置:例如
<depend>MySQL</depend>。这能确保在服务器重启后,先启动数据库,等数据库就绪后再启动你的 JAR 包,避免程序启动时因连接不上数据库而报错。如果你的服务依赖 MySQL 或 Redis,可以在 XML 中添加<depend>MySQL</depend>,确保数据库启动后再启动 JAR 包。 -
<stopparentprocessfirst> : - 含义:在停止服务时,WinSW 会先向 Java 进程发送
Ctrl+C 信号,而不是直接调用 Windows 的TerminateProcess,等同于任务管理器的结束任务。 -
<stoptimeout> : - 缓冲时间:如果发送停止信号后,Java 进程在 30 秒内还没退出,WinSW 才会执行“强杀”动作。避免出现异常的服务无法杀死导致死循环。
相对完善的启动环境配置,无前置依赖,完善的稳定配置,福袋了JVM命令、日记文件大小、日志文件记录数量、自动重启策略、缓冲安全停止、无法停止强制杀死时间配置。
<service>
<id>my-app-service</id>
<name>My Java Application Service</name>
<description>这是一个自动启动的 SpringBoot 服务</description>
<executable>java</executable>
<arguments>-Xms512m -Xmx2048m -Dfile.encoding=utf-8 -jar "D:\my-program\my-service\my-app.jar"</arguments>
<startmode>Automatic</startmode>
<log mode="roll">
<logpath>D:\my-program\my-service\logs</logpath>
<sizeThreshold>10240</sizeThreshold>
<keepFiles>10</keepFiles>
</log>
<onfailure action="restart" delay="10 sec"/>
<onfailure action="restart" delay="30 sec"/>
<onfailure action="none" />
<stopparentprocessfirst>true</stopparentprocessfirst>
<stoptimeout>30 sec</stoptimeout>
</service>
4. 安装与管理服务
你需要以 管理员身份 运行命令行,进入该目录执行以下命令:
4.1注册服务
my-service.exe install
4.2启动服务
my-service.exe start
4.3停止服务
my-service.exe stop
4.4卸载服务
需要注意,卸载服务需要保证已经停止服务,否则无法卸载
my-service.exe uninstall
4.5查看状态
my-service.exe status
为什么推荐 WinSW
| 特性 | WinSW | 任务计划程序 | 启动文件夹快捷方式 |
|---|---|---|---|
| 开机自启 | 只要系统启动即运行,无需用户登录 | 需手动设置“不管用户是否登录” | 必须用户登录桌面后才启动 |
| 进程守护 | 程序崩溃后可自动重启 | 不支持自动重启 | 不支持 |
| 日志记录 | 自动接管标准输出并滚动记录日志 | 难以捕获后台日志 | 需要手动重定向 |
| 管理便捷 | 集成在 Windowsservices.msc中 | 需在任务计划程序库查找 | 难以管理 |
