|
|
# Windows 将 JAR 注册为系统服务:开机自启动与异常重启
更新日期:2026-10-23
## 一、适用场景
本文介绍如何使用 **NSSM**,将需要长期运行的 Java JAR 程序注册为 Windows 系统服务,实现:
- 服务器重启后自动启动,不需要登录桌面。
- 关闭命令行窗口或断开远程桌面后,程序继续运行。
- Java 进程退出后按配置重新启动。
- 使用 Windows“服务”管理器统一启动、停止和查看状态。
适用于已安装兼容 Java 运行环境、允许安装系统服务的 Windows / Windows Server。安装和管理服务需要管理员权限。
> 普通的 `java -jar` 程序不是 Windows 原生服务,不能直接使用 `sc.exe create` 指向 Java 命令来完成可靠的服务注册。NSSM 负责与 Windows 服务控制管理器通信,并管理 Java 子进程。
>
> 本文面向长期运行的服务端程序,不适合执行完任务就应退出的一次性 JAR,也不适合需要在用户桌面显示窗口的交互程序。
## 二、占位符说明
**执行前,必须将下面所有占位符替换为自己的实际内容。** 不要原样执行示例。
| 占位符 | 含义 | 注意事项 |
| --- | --- | --- |
| `YOUR_SERVICE_NAME` | 服务内部名称 | 建议使用英文字母、数字、下划线;同一台机器必须唯一 |
| `YOUR_SERVICE_DISPLAY_NAME` | 服务管理器中的显示名称 | 可以与内部名称不同 |
| `C:\YOUR_NSSM_DIR` | NSSM 所在的固定目录 | 安装后不可随意移动或删除 |
| `C:\YOUR_JAVA_DIR` | Java 安装目录 | 使用与应用兼容的实际 Java 版本,不依赖当前用户的 PATH |
| `D:\YOUR_APP_DIR` | 应用部署目录 | 建议使用本地固定磁盘的绝对路径 |
| `YOUR_APP.jar` | 实际 JAR 文件名 | 必须与磁盘上的文件名一致 |
| `YOUR_CONFIG.yml` | 可选的外部配置文件名 | 仅在应用确实支持并需要外部配置时使用 |
本文所有命令块均按 **CMD** 编写。请使用“以管理员身份运行”的命令提示符执行,不要直接按 PowerShell 的语法解释带引号的可执行文件路径。
示例目录结构:
```text
C:\YOUR_NSSM_DIR\
└─ nssm.exe
D:\YOUR_APP_DIR\
├─ YOUR_APP.jar
├─ YOUR_CONFIG.yml (可选)
└─ logs\
```
## 三、安装前检查
### 3.1 准备 NSSM
从官方来源下载:
- [NSSM 下载页面](https://nssm.cc/download)
- [NSSM 使用说明](https://nssm.cc/usage)
根据服务器操作系统架构选择相应版本。将 `nssm.exe` 放到固定位置,例如占位目录 `C:\YOUR_NSSM_DIR`,不要放在临时目录或随后会被删除的下载目录中。
生产使用前,应核对下载来源、安全策略及目标 Windows 版本的兼容性。
### 3.2 确认 Java 与 JAR
```bat
"C:\YOUR_JAVA_DIR\bin\java.exe" -version
dir "D:\YOUR_APP_DIR\YOUR_APP.jar"
```
确认以下事项:
1. Java 版本能够运行该 JAR。
2. 应用在相同 Java、JVM 参数、工作目录和配置下能够手动正常启动。
3. 已准备好应用需要的数据库、缓存、证书及其他依赖。
4. 手动测试结束后,正常停止该实例,再启动服务,避免同一个程序重复运行和端口冲突。
> 如果原来使用 BAT 启动,应先核对 BAT 中的 JVM 参数、环境变量、工作目录和应用参数。直接把 JAR 注册为服务,不会自动执行 BAT 中的这些设置。不要遗漏原有鉴权、配置加载、资源限制或启动前检查。
## 四、创建 Windows 服务
### 4.1 打开安装窗口
在管理员 CMD 中执行:
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" install YOUR_SERVICE_NAME
```
### 4.2 填写 Application 页面
| 设置项 | 填写示例 |
| --- | --- |
| Path | `C:\YOUR_JAVA_DIR\bin\java.exe` |
| Startup directory | `D:\YOUR_APP_DIR` |
| Arguments | `-jar "D:\YOUR_APP_DIR\YOUR_APP.jar"` |
**字段含义:**
- **Path**:填写 `java.exe` 的完整路径,不是 JAR 路径;GUI 字段直接填写路径,不需要给整个字段额外添加引号。
- **Startup directory**:应用工作目录,决定相对配置、相对日志等路径从哪里解析。
- **Arguments**:Java 启动参数;包含空格的文件路径必须使用双引号包围。
需要 JVM 内存参数时,Arguments 可以按以下格式填写:
```text
-Xms256m -Xmx1024m -jar "D:\YOUR_APP_DIR\YOUR_APP.jar"
```
上述内存值仅用于展示语法,不是适合所有机器的推荐配置。已有生产参数应保留,并按服务器内存及程序需求调整。
参数顺序为:
```text
[JVM参数] -jar "JAR完整路径" [应用参数]
```
例如,**仅对于支持该参数的 Spring Boot 应用**,可以使用额外外部配置:
```text
-Xms256m -Xmx1024m -jar "D:\YOUR_APP_DIR\YOUR_APP.jar" --spring.config.additional-location="file :/YOUR_APP_DIR/YOUR_CONFIG.yml"
```
`spring.config.additional-location` 表示增加配置位置,不是通用于所有 JAR 的参数。外部配置可能覆盖已有属性,应根据实际框架版本及应用要求设置。
### 4.3 设置服务账号
在 **Log on** 页面选择运行账号:
- 生产环境建议使用符合应用要求的专用低权限服务账号。
- 账号至少需要 Java/JAR/配置的读取权限,以及日志、缓存、临时目录等实际写入位置的权限。
- 如果使用自定义账号,需要具备“作为服务登录”的权限;域策略可能限制或撤销此权限。
- 不要仅为方便而长期使用管理员账号或高权限的 LocalSystem。
如果应用访问网络共享,应使用具有相应网络权限的账号,并同时检查共享权限和文件系统权限。不要依赖桌面登录会话映射出来的盘符。
### 4.4 设置必要环境变量
如果原启动方式依赖自定义环境变量,应在 NSSM 的 **Environment** 页面配置,或按运维规范设置服务可用的系统环境变量。每行使用:
```text
YOUR_ENV_NAME=YOUR_ENV_VALUE
```
不要假定服务会继承当前桌面用户的环境。环境变量修改后通常需要重启对应服务;若服务仍读取旧的系统环境,应检查服务启动链及系统环境刷新情况。
密码、Token 和密钥应按内部安全规范管理,不要写进公开教程、截图或共享命令记录中。环境变量本身也不是加密的秘密存储。
填写完成后点击 **Install service**。
## 五、配置开机自动启动和退出后重启
### 5.1 自动延迟启动
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME DisplayName "YOUR_SERVICE_DISPLAY_NAME"
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME Start SERVICE_DELAYED_AUTO_START
```
“自动(延迟启动)”表示系统启动后自动启动服务,无需用户登录。它不是精确延迟多少秒的定时器,也不保证数据库、网络等依赖届时一定已就绪。
如果不需要延迟,可以改为普通自动启动:
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME Start SERVICE_AUTO_START
```
以上两种启动类型**二选一**,后设置的值覆盖先前设置。
### 5.2 Java 进程退出后重新启动
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME AppExit Default Restart
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME AppRestartDelay 10000
```
表示 Java 子进程退出后,默认重新启动,并设置至少 10 秒的重启等待;NSSM 的快速退出节流机制可能进一步延长等待。
注意:
- 此设置默认也会重启正常退出的 Java 程序,所以仅适合应长期运行的应用。
- 使用服务停止命令进行正常维护,不要通过反复强杀 Java 来停止服务。
- **进程仍在但应用卡死、不响应,并不属于“进程退出”**,不能只靠此设置解决;需要另行配置业务健康检查和告警。
### 5.3 给应用预留正常退出时间
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME AppStopMethodConsole 30000
```
这会为控制台停止通知阶段设置 30 秒等待。应用应正确响应停止信号、提交必要数据并释放资源。
这不是“保证所有任务都会在30秒内完成”,也不是永远不会强制终止。实际停止行为还受 NSSM 后续停止方法、Windows 关机流程和应用本身影响。维护前应先停止接收新任务,并等待重要任务结束;长任务应用需按自身要求调整退出机制。
## 六、配置控制台日志和轮转
### 6.1 创建日志目录
```bat
if not exist "D:\YOUR_APP_DIR\logs" mkdir "D:\YOUR_APP_DIR\logs"
```
确认服务账号对该目录具有写入权限。
### 6.2 重定向标准输出与错误输出
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME AppStdout "D:\YOUR_APP_DIR\logs\service-out.log"
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME AppStderr "D:\YOUR_APP_DIR\logs\service-error.log"
```
### 6.3 启用日志轮转
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME AppRotateFiles 1
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME AppRotateOnline 1
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME AppRotateBytes 10485760
```
示例按约 10 MiB 的阈值触发轮转,实际切分时点可能受输出缓冲等影响。
> 日志轮转不等于自动清理历史日志。还需要按磁盘容量、安全审计和业务要求制定归档/保留策略。应用自身的日志文件仍由应用的日志配置管理,不受上述控制台轮转设置统一控制。
## 七、启动服务并验证
### 7.1 启动
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" start YOUR_SERVICE_NAME
```
### 7.2 查看服务状态
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" status YOUR_SERVICE_NAME
sc.exe query YOUR_SERVICE_NAME
```
也可以按 `Win + R`,输入:
```text
services.msc
```
在“服务”管理器中确认服务名称、启动类型和登录账号。
### 7.3 检查应用是否真正可用
必须同时确认:
1. 应用日志出现实际启动成功的信息,没有持续重启或配置错误。
2. 应用预期的端口已正常监听(仅针对监听端口的应用)。
3. 使用客户端、浏览器或应用实际提供的健康接口访问成功。
4. 数据库、缓存、存储等必要依赖连接正常。
**Windows服务“正在运行”不等于应用已准备好提供业务服务。** NSSM可能仍在启动Java,或者等待一个反复失败的进程重新启动。
## 八、重启服务器后的验收
在安排好的维护时间内进行,避免中断实际业务:
1. 确认服务已配置为自动或自动延迟启动。
2. 确认数据库、缓存等必要依赖也有正确的启动安排;应用应具备合理的连接重试机制。
3. 重启服务器。
4. 尽量在尚未登录桌面时,从另一台机器检查业务是否恢复,验证不依赖交互登录。
5. 登录后核对应用启动日志、服务状态及业务功能。
6. 排查是否还存在启动文件夹、计划任务、第三方守护工具等重复启动同一实例的配置,避免端口冲突。
如果确实需要配置本机服务依赖,应先核实数据库等组件的**实际Windows服务内部名称**以及已有依赖,不要直接照抄其他机器的服务名,也不要无意覆盖原依赖列表。
## 九、日常维护命令
### 启动、停止、重启
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" start YOUR_SERVICE_NAME
"C:\YOUR_NSSM_DIR\nssm.exe" stop YOUR_SERVICE_NAME
"C:\YOUR_NSSM_DIR\nssm.exe" restart YOUR_SERVICE_NAME
```
每行是一个独立操作,按需要选择执行,不必连续执行全部命令。
### 修改配置
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" edit YOUR_SERVICE_NAME
```
修改运行路径、参数、账号、环境变量或日志设置后,按变更要求重新启动服务并检查业务。
### 禁止自动启动
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" set YOUR_SERVICE_NAME Start SERVICE_DEMAND_START
```
将启动类型改为“手动”,不会自动停止当前运行中的服务。如需停止,另行执行停止命令。
### 删除服务注册
**确认不再需要该服务后再执行:**
```bat
"C:\YOUR_NSSM_DIR\nssm.exe" stop YOUR_SERVICE_NAME
"C:\YOUR_NSSM_DIR\nssm.exe" remove YOUR_SERVICE_NAME confirm
```
删除服务注册不会自动删除 JAR、配置或日志。删除前应保留必要备份。
## 十、更新 JAR 的推荐步骤
1. 安排维护时间,停止接收新任务,等待重要操作完成。
2. 停止服务,并确认对应 Java 进程已经退出;无法正常退出时先查原因。
3. 备份旧 JAR、配置及必要的版本信息,不要直接覆盖后再想办法回退。
4. 替换新的 JAR。若文件名或Java路径变化,同步修改服务配置。
5. 启动服务,检查日志、依赖和实际业务功能。
6. 如有问题,停止服务后恢复旧版本,再重新验证。
> 如果升级包含数据库结构或数据迁移,恢复旧JAR不一定能完整回退,必须额外遵循该版本的数据库备份与兼容性方案。
## 十一、常见问题排查
| 现象 | 可能原因 | 排查方向 |
| --- | --- | --- |
| `Unable to access jarfile` | JAR路径错误、文件不存在、账号无读取权限 | 使用绝对路径,检查文件名、双引号和服务账号权限 |
| `UnsupportedClassVersionError` | Java版本低于程序要求 | 使用与构建目标兼容的Java,并更新服务中的绝对路径 |
| JVM参数无法识别 | 将旧Java版本参数直接复制到新版本 | 按实际Java版本调整,不盲目复用GC日志等参数 |
| 手动运行正常,服务启动失败 | 工作目录、环境变量、账号权限不同 | 比较服务配置与原手动启动环境 |
| 服务启动后一直重启 | Java启动即失败、配置错误、依赖未就绪 | 先看标准错误和应用日志,不要只提高重启频率 |
| 提示端口占用 | 手动实例、计划任务或其他服务重复启动 | 确认占用端口的实际进程,再正常停止重复实例 |
| 服务器重启后未启动 | 启动类型不正确、NSSM/Java路径失效、账号登录失败 | 检查服务属性和Windows事件查看器中的服务错误 |
| 服务已运行但无法访问 | 业务未就绪、监听地址错误、防火墙或依赖异常 | 检查日志、实际端口和业务访问路径,不直接关闭防火墙 |
| 日志文件没有生成 | 日志目录不存在或服务账号无写权限 | 预建目录、检查绝对路径和权限 |
| 找不到网络盘文件 | 依赖当前桌面会话映射盘符 | 使用具备权限的服务账号和UNC路径,并测试网络就绪情况 |
| 显示“登录失败” | 服务账号密码变化、账号被禁用或缺少登录权限 | 在安全管理流程下更新账号并检查“作为服务登录”权限 |
| 直接注册Java后报1053 | 普通Java进程未实现Windows服务协议 | 使用NSSM等合适的服务包装器,并查看具体事件日志 |
若修改了环境或配置仍异常,可以同时检查:
- NSSM重定向的标准输出和标准错误日志。
- 应用本身的日志。
- Windows“事件查看器”中的应用程序及系统日志。
## 十二、发布与运维检查清单
- [ ] 已替换本文占位符,未遗留其他机器的路径或账号。
- [ ] 使用Java和NSSM的固定绝对路径,版本与操作系统兼容。
- [ ] 服务名唯一,工作目录和JAR参数正确。
- [ ] 原启动脚本中的必要参数、环境变量和启动前条件已核对。
- [ ] 使用合适的服务账号,配置/日志/临时文件权限满足要求。
- [ ] 已设置自动启动及适合业务的退出重启策略。
- [ ] 已设置日志轮转以及独立的历史日志保留策略。
- [ ] 关闭远程桌面后程序仍能正常提供服务。
- [ ] 已验证服务器重启后无需登录即可恢复业务。
- [ ] 已确认没有重复启动同一实例的计划任务或启动项。
- [ ] 已准备好JAR、配置及数据库变更所需的备份和回退方案。
**总结:NSSM负责把Java进程接入Windows服务管理;自动启动、退出重启和业务健康是三个不同问题,需要分别配置并验证。**
|
|