Windows 基于 NSSM 2.24 实现 Bat/Java 应用系统服务托管、开机自启、故障自愈

一、前言与业务背景、技术选型分析

1.1 业务背景

在 Windows Server 企业服务器运维场景中,SpringBoot Java 应用、自定义批处理脚本等程序,默认依赖桌面会话运行,存在三大生产级短板:

  1. 普通 Bat 双击运行依附用户会话,远程桌面断开、用户注销后程序直接终止,无法后台常驻;
  2. 原生开机自启方式仅支持启动,不具备进程监控、异常崩溃自动恢复能力,业务中断无人自愈;
  3. 原生方案无标准化日志托管、权限管控,生产环境可运维性、安全性不足。

因此业务需要一套可后台常驻、开机自启、进程故障自愈、日志分离、权限最小化、稳定可靠的 Windows 服务托管方案。

1.2 市面主流技术方案差异化对比

Windows 平台将普通程序转为系统服务、实现常驻守护的主流方案共 5 类,从原生性、故障自愈、日志能力、运维成本、合规性维度进行对比分析:

实现方案第三方依赖进程故障自愈标准系统服务日志托管能力运维难度适用场景
Windows 任务计划程序无不支持否极弱低仅需简单开机自启,无高可用需求
srvany+instsrv 微软原生工具系统自带工具需依赖系统恢复策略,无进程级监控是弱高(注册表配置繁琐)涉密、信创、禁止开源工具场景
自研 Bat/PowerShell 守护脚本无支持简易守护否自定义实现中高合规、零第三方依赖场景
国产第三方进程守护工具国产第三方支持是一般低国产化替换项目
NSSM 开源服务托管工具轻量开源原生进程级精准自愈是完善(日志分离托管)极低通用企业生产环境(本文方案)

1.3 最终选择 NSSM 的核心优势

综合生产稳定性、运维成本、功能完整性,本文选用 NSSM 2.24 稳定版,核心优势区别于其他方案:

  1. 对比 srvany:自带进程实时监控,可精准感知程序运行状态,杜绝「服务显示运行、程序已崩溃」的虚假存活问题;
  2. 对比计划任务:生成标准 Windows 系统服务,支持权限管控、开机自启,完全不依赖用户会话;
  3. 原生支持日志重定向,标准输出、错误日志物理分离,无需额外脚本处理日志;
  4. 支持细粒度进程退出码策略、重启延迟、崩溃限流,可有效规避服务死循环重启问题;
  5. 图形界面 + 命令行双操作模式,部署与运维门槛低,适配企业标准化运维流程。

二、NSSM 工具官方简介

2.1 官方定义

NSSM 全称为 Non-Sucking Service Manager,是一款轻量、开源、免费的 Windows 服务辅助托管工具。
官方网站:https://nssm.cc
结合官网原文翻译与功能解读,核心特性如下:

  1. 传统 Windows 服务托管工具(如 srvany)存在缺陷:无法监控应用进程状态,易出现服务状态与实际运行状态不一致的问题;
  2. NSSM 会实时监控托管进程,应用异常退出、崩溃终止时可自动重启,保证服务状态真实有效;
  3. 策略灵活:对于稳定性较高的应用,可关闭 NSSM 重启能力,交由 Windows 系统原生恢复机制处理故障;
  4. 运行日志自动写入 Windows 系统事件日志,可通过系统事件查看器排查启停、运行异常;
  5. 内置图形化服务安装、编辑、卸载界面,2.19 及以上版本功能完善、稳定性大幅提升。

2.2 版本选型说明

本文生产环境选用 NSSM 2.24(官方稳定版),放弃预览版、最新版本。该版本在 Windows Server 全系列系统中兼容性最优、已知 BUG 最少,也是企业运维领域使用最广泛的版本。

三、NSSM 官方下载、校验、目录规范

3.1 官方唯一下载地址

官方下载页面:https://nssm.cc/download
在这里插入图片描述

3.2 安装包解压目录结构

下载压缩包名称:nssm-2.24.zip,解压后目录结构固定如下:

  • src:工具源码目录
  • win32:32 位 Windows 系统可执行程序目录
  • win64:64 位 Windows 系统可执行程序目录(本文使用)
  • ChangeLog.txt:版本更新日志文档
  • README.txt:官方使用说明文档

📷 NSSM 解压后完整目录结构
在这里插入图片描述

3.3 文件哈希安全校验(防篡改、防植入)

生产环境使用前,必须校验文件哈希值,防止文件被篡改、植入恶意程序。
NSSM 2.24 win64 原版 SHA256 哈希值:

f689ee9af94b00e9e3f0bb072b34caaf207f32dcb4f5782fc9ca351df9a06c97

校验命令(管理员 CMD 执行)

:: 切换至64位程序目录
cd /d D:\softwares\nssm-server\nssm-2.24\win64
:: SHA256哈希校验
certutil -hashfile nssm.exe SHA256

校验规则:命令输出的哈希值与官方值完全一致,则为原版安全文件;若不一致,立即删除文件并重新从官网下载。

📷 文件哈希校验执行结果
在这里插入图片描述
溯源判定:该哈希为官方原版有效值四大核验依据(可自行复核)

  1. 官网源码打包溯源:NSSM 2.24 正式版发布于2014-08-31,官网Git仓库tag打包编译的win64架构nssm.exe,固定生成该SHA256指纹,官网下载包为同源编译产物。
  2. 本文实操原生核验:本文全程从 nssm.cc 官网直下2.24压缩包,解压后管理员CMD本地核验,原生输出上述哈希,非手动伪造录入。
  3. 版本区分避坑:2017预览版2.24-101为另一组哈希,本文选用稳定正式版2.24,二者哈希不互通,不可混用比对。
    核验逻辑:只要官网原生编译文件,哈希永久固定;一旦被捆绑木马、修改代码、重编译,哈希值会直接变更,即可判定文件非原版。

3.4 生产标准化目录规划

统一固定路径,禁止使用中文、空格、桌面临时目录,便于后期运维迁移、权限管控:

D:\softwares\nssm-server                  # 总根目录
D:\softwares\nssm-server\run-server       # JDK、Jar包、启动脚本、日志根目录
D:\softwares\nssm-server\nssm-2.24        # NSSM 主目录
D:\softwares\nssm-server\nssm-2.24\win32  # NSSM 32位程序目录
D:\softwares\nssm-server\nssm-2.24\win64  # NSSM 64位程序目录
D:\softwares\nssm-server\run-server\logs  # 应用日志目录(需手动提前创建)

四、Bat 启动脚本

4.1 脚本说明

文件路径:D:\softwares\nssm-server\run-server\runjava.bat
作用:加载 JDK 运行环境、配置 JVM 参数、启动 SpringBoot 项目,适配 NSSM 后台托管,不污染系统全局环境。

4.2 最终版脚本

@echo off
:: 关闭脚本冗余输出
:: 开启本地环境隔离 + 变量延迟扩展
setlocal enabledelayedexpansion

:: 配置JVM运行参数:服务端运行模式、统一字符编码
set JAVA_OPTS= ^
-server ^
-Dfile.encoding=GBK ^
-Dapp.name=OAuthApiService

:: JDK绝对路径(根据实际部署路径修改)
set JAVA_HOME=D:\softwares\nssm-server\run-server\zulu17.50.19-ca-jdk17.0.11-win_x64
:: 追加JDK运行环境至系统变量,保留原有Path,不覆盖系统命令
set Path=%JAVA_HOME%\bin;%Path%

:: JDK9及以上版本已废弃dt.jar、tools.jar,删除冗余CLASSPATH配置,规避报错

:: 切换到 jar 所在目录(强制跨盘符)
cd /d D:\softwares\nssm-server\run-server

:: 后台启动SpringBoot项目,指定运行环境为 dev
:: 多服务场景可替换为自定义进程名:javaw-nssm.exe
:: java %JAVA_OPTS% -jar project-api.jar --spring.profiles.active=dev
:: 自定义服务名称javaw-nssm.exe
javaw-nssm.exe %JAVA_OPTS% -jar project-api.jar  --spring.profiles.active=dev

4.3 核心指令严谨解析

  1. setlocal:创建局部环境域,脚本内定义的变量仅当前会话生效,脚本执行结束后自动还原系统环境,杜绝全局变量污染;
  2. enabledelayedexpansion:开启变量延迟解析,兼容后续脚本迭代(循环、嵌套逻辑),属于生产环境通用规范写法;
  3. cd /d:支持跨盘符切换工作目录,保证 Jar 包、配置文件正常读取;
  4. 移除 CLASSPATH:JDK 9+ 彻底废弃 dt.jar、tools.jar,该配置无效且易引发拼写错误,生产环境直接删除。

4.4 多服务进程区分优化(可选生产方案)

单服务器部署多个 Java 服务时,为区分进程、方便运维排查,可以做如下优化:

  1. 进入 JDK 的 bin 目录,复制原生 javaw.exe,重命名为 javaw-nssm.exe;
  2. 修改脚本启动命令:
javaw-nssm.exe %JAVA_OPTS% -jar project-api.jar --spring.profiles.active=dev

五、NSSM 图形化部署系统服务(2.24 原版专属配置)

5.1 安装服务命令

以管理员身份打开 CMD,执行以下命令:

cd /d D:\softwares\nssm-server\nssm-2.24\win64
nssm.exe install OAuthApiService

命令执行后,自动弹出 NSSM 服务配置窗口。
📷 NSSM 服务编辑器主界面在这里插入图片描述

5.2 分标签精准配置(适配 NSSM2.24 原版界面)

重要说明:NSSM 2.24 无独立的 Log、Startup、Recovery 标签,所有配置以当前界面为准。

5.2.1 Application 标签(核心路径配置)
  • Path:D:\softwares\nssm-server\run-server\runjava.bat(启动脚本完整路径)
  • Startup directory:D:\softwares\nssm-server\run-server(脚本所在工作目录)

📷 Application 标签路径配置
在这里插入图片描述

5.2.2 I/O 标签(日志托管配置)

NSSM 通过 I/O 标签实现标准输出、错误日志分离:

  • Output (stdout):D:\softwares\nssm-server\run-server\logs\stdout.log(正常运行日志)
  • Error (stderr):D:\softwares\nssm-server\run-server\logs\stderr.log(异常错误日志)

📷 I/O 标签日志配置
截图内容:选中 I/O 标签,标注两个日志路径输入框及对应内容

5.2.3 Details 标签(启动类型配置)
  • 常规业务服务:选择 Automatic(系统开机自动启动)
  • 依赖网络、数据库的服务:选择 Automatic (Delayed Start)(系统启动完成后延迟启动)

📷 Details 标签启动类型配置
选中 Details 标签,标注 Startup type 下拉选项。
在这里插入图片描述

5.2.4 Log on 标签(权限最小化,生产安全核心)

安全原则:禁止使用 LocalSystem、Administrator 等高权限账户,遵循最小权限原则。
推荐使用系统内置账户:

  1. 勾选 This account;
  2. 用户名填写:NT AUTHORITY\NetworkService;
  3. 密码输入框留空(系统内置账户无密码)。

📷 Log on 标签账户权限配置
选中 Log on 标签,标注账户选择项、用户名输入框。
在这里插入图片描述

5.3 服务创建成功标识

所有参数配置完成后,点击窗口 OK 按钮。CMD 控制台输出以下内容,代表服务创建成功:

Service "OAuthApiService" installed successfully!

📷 服务创建成功
在这里插入图片描述
📷 加入系统服务OAuthApiService
在这里插入图片描述

六、服务基础运维命令

所有服务操作命令,均需在管理员 CMD 中执行:

:: 启动系统服务
net start OAuthApiService

:: 停止系统服务
net stop OAuthApiService

:: 重启服务(先停止再启动)
net stop OAuthApiService && net start OAuthApiService

:: 打开 Windows 系统服务管理器(图形化查看所有服务)
services.msc

:: 编辑已存在的 NSSM 服务配置(重新打开图形配置窗口)
nssm.exe edit OAuthApiService

:: 卸载服务(执行前必须先停止服务,谨慎操作)
nssm.exe remove OAuthApiService

七、生产安全加固方案

7.1 目录权限加固(适配 NetworkService 账户)

服务以 NetworkService 账户运行,需手动分配目录最小权限,防止越权攻击:

  1. 右键目录 D:\softwares\nssm-server\run-server → 属性 → 安全 → 编辑;
  2. 点击「添加」,搜索并选中用户 NETWORK SERVICE;
  3. 权限配置:允许「修改、读取 & 执行、列出文件夹内容、读取、写入」,按需勾选「拒绝:完全控制」;
  4. 应用范围选择:此文件夹、子文件夹和文件。

7.2 杀毒 / EDR 白名单配置

NSSM 具备服务创建、进程托管能力,会被主流杀毒软件、终端安全(EDR)标记为 RiskTool(风险工具),属于正常误报,需添加白名单:

  1. 白名单目录:D:\softwares\nssm-server;
  2. 安全策略优化:限制 NSSM 仅允许创建 OAuthApiService 单一服务,拦截未知服务创建行为。

八、NSSM 2.24 故障自愈策略配置

8.1 版本限制严谨说明

NSSM 2.24 无 Recovery 图形界面,不支持 AppResetFailCount、AppMaxFailures 等参数,所有自愈策略仅可通过命令行配置。

8.2 自愈策略配置命令(精准有效、带注释)

:: 切换至 NSSM 64位程序目录
cd /d D:\softwares\nssm-server\nssm-2.24\win64

:: 退出码-1:进程被强制杀死 → 自动重启
nssm.exe set OAuthApiService AppExit -1 Restart
:: 退出码0:程序正常退出 → 自动重启
nssm.exe set OAuthApiService AppExit 0 Restart
:: 退出码1:常规业务异常 → 自动重启
nssm.exe set OAuthApiService AppExit 1 Restart
:: 退出码2:严重运行异常 → 自动重启
nssm.exe set OAuthApiService AppExit 2 Restart

:: 单独禁用某类异常的自动重启(按需使用)
nssm.exe set OAuthApiService AppExit 1 Ignore

:: 重启延迟3000毫秒(3秒),预留端口、系统资源释放时间
nssm.exe set OAuthApiService AppRestartDelay 3000

:: 崩溃限流1500毫秒,防止短时间内频繁崩溃导致死循环重启
nssm.exe set OAuthApiService AppThrottle 1500

8.3 配置校验命令(验证参数生效)

:: 查看各退出码对应的处理策略
nssm.exe get OAuthApiService AppExit -1
nssm.exe get OAuthApiService AppExit 0
nssm.exe get OAuthApiService AppExit 1
nssm.exe get OAuthApiService AppExit 2

:: 查看重启延迟、崩溃限流配置
nssm.exe get OAuthApiService AppRestartDelay
nssm.exe get OAuthApiService AppThrottle

📷 自愈策略配置命令执行验证
在这里插入图片描述

8.4 关键现象解释

执行 nssm set AppExit xx Restart 时,若提示 Reset parameter to its default:
该提示并非报错。NSSM2.24 默认所有退出码策略为 Restart,当配置值与默认值一致时会触发该提示,策略实际已生效,可通过 get 命令二次校验。
补充:Ignore 关键字作用:指定退出码触发时,不执行自动重启,用于区分人为运维关停和业务故障崩溃。

九、功能测试方案

前置校验(自愈测试必做,否则会出现重启失效)
执行故障自愈测试前,必须完成目录权限校验:

  1. 进入项目根目录 D:\softwares\nssm-server\run-server;
  2. 右键文件夹 → 属性 → 安全 → 编辑;
  3. 确认用户 NETWORK SERVICE 已添加,权限配置:允许「修改 & 读取 & 执行、列出文件夹内容、读取、写入」;
  4. 若未添加该用户,需手动新增并分配权限,否则 NSSM 无法拉起新 Java 进程,自愈功能完全失效。
    在这里插入图片描述

9.1 故障自愈测试(核心功能验证)

  1. 管理员 CMD 执行 tasklist | findstr javaw,获取 Java 进程 PID;
  2. 执行 taskkill /F /PID 对应PID,强制终止运行进程;
  3. 等待 4 秒(大于 3 秒重启延迟,规避限流阈值干扰);
  4. 再次执行 tasklist | findstr javaw 观测结果:输出全新 PID 的javaw-nssm.exe进程,代表自愈策略生效。
  5. 观测结果:等待 3 秒后,系统自动生成新的 Java 进程,代表自愈策略生效。

9.2 受控关停测试(区分运维操作与故障)

执行命令 net stop OAuthApiService,服务正常停止,且不会触发自动重启,符合生产运维逻辑。

📷 进程杀死、自动重启完整测试流程
CMD 依次执行查询进程、杀进程、再次查询进程的完整命令与输出,展示 PID 变化。
在这里插入图片描述

十、生产踩坑总结与精准解决方案

10.1 脚本环境类问题

  1. 问题:CLASSPATH 变量大小写拼写错误,导致应用启动异常
    • 原因:脚本中 %JAVA_HOMe% 大小写不统一;
    • 解决方案:统一变量名 %JAVA_HOME%,JDK17 直接删除 CLASSPATH 冗余配置。
  2. 问题:Path 变量被覆盖,系统基础命令失效
    • 原因:原脚本直接覆盖系统 Path 变量;
    • 解决方案:改为追加模式 set Path=%JAVA_HOME%\bin;%Path%。
  3. 问题:启动后提示找不到 Jar 包
    • 原因:NSSM 未配置 Startup directory 工作目录,或路径包含中文 / 空格;
    • 解决方案:严格配置工作目录,全路径使用纯英文、无空格字符。

10.2 NSSM 版本兼容类问题

  1. 问题:执行 AppResetFailCount、AppMaxFailures 提示参数无效
    • 原因:该类参数为高版本 NSSM 专属,2.24 版本本身不支持;
    • 解决方案:放弃无效命令,通过 Windows 服务「恢复」面板补充失败计数重置能力。
  2. 问题:AppExit Default 全局配置不生效
    • 原因:NSSM 2.24 不支持 Default 通配符;
    • 解决方案:逐个配置具体退出码的处理策略。
  3. 问题:配置 Restart 提示重置为默认值
    • 原因:配置值与软件默认策略一致,属于正常提示,非程序 BUG;
    • 解决方案:无需处理,使用 get 命令校验配置即可。

10.3 目录权限类高频故障(新测试问题补充)

  1. 问题:执行taskkill杀死 Java 进程,等待 4 秒以上无新进程自动拉起;手动双击runjava.bat可正常启动业务进程
    • 原因:项目目录安全权限中未添加NETWORK SERVICE系统账户,服务运行账户无读写、执行权限,NSSM 尝试拉起进程时直接闪退;
    • 复现特征:本地脚本运行正常,NSSM 托管下自愈重启完全失效;
    • 解决方案:
      ① 右键D:\softwares\nssm-server\run-server → 属性 → 安全 → 编辑 → 添加;
      ② 搜索并选中用户NETWORK SERVICE;
      ③ 分配权限:允许读取 & 执行、列出文件夹内容、读取、写入;
      ④ 权限应用范围:此文件夹、子文件夹和文件;
      ⑤ 重启服务后重新测试自愈功能。
  2. 问题:执行 taskkill 命令提示「拒绝访问」
    • 原因:服务进程由系统账户运行,普通用户权限不足;
    • 解决方案:使用管理员身份运行 CMD 执行操作。
  3. 问题:服务启动后无日志文件、无法写入日志
    • 原因:NetworkService 账户未分配目录读写权限;
    • 解决方案:按照本文权限配置章节,完整配置文件夹安全权限。

10.5 进程重启逻辑现象误区

  1. 现象:杀掉 Java 业务进程后,服务面板仍显示「正在运行」,短时间查询无进程,延时后出现全新 PID 进程
    • 原理:Windows 服务状态由 NSSM 宿主进程维护,与 Java 子进程解耦;配置AppRestartDelay延时重启,延时结束后生成新进程;PID 变化代表正常自愈。
  2. 现象:频繁短时间杀进程后,永久不再自动重启 Java 进程
    • 原因:短间隔重复崩溃触发AppThrottle限流保护;
    • 解决方案:重启服务重置限流计数器,合理调大限流阈值,测试时两次杀进程间隔大于限流毫秒数。

十一、总结

本文基于官方原版NSSM 2.24稳定版,搭建Windows环境Java业务、Bat脚本标准化系统服务托管方案,精准解决程序依附桌面会话、服务虚假运行、进程崩溃无自愈、业务日志无管控、运行账户权限过高五大生产运维痛点,完整实现后台离线常驻、系统开机自启、进程级故障自愈、业务日志分离、账户最小权限运行核心能力。相较于Windows任务计划、srvany等传统托管方案,本方案配置简单、运维门槛低、进程守护稳定性更强。

十二、附录:常用命令速查表

使用前置要求:全部命令需 管理员身份 CMD执行,执行前需cd切换至nssm-win64目录

功能场景执行命令生产运维备注
文件 SHA256 哈希安全校验certutil -hashfile nssm.exe SHA256校验文件完整性,防止恶意篡改
安装系统服务nssm.exe install 服务名弹出可视化配置窗口,交互式部署
编辑已有服务配置nssm.exe edit 服务名修改脚本路径、日志、权限等参数
卸载系统服务nssm.exe remove 服务名卸载前必须先停止服务,严禁强制卸载
启动系统服务net start 服务名触发NSSM自动拉起业务子进程
停止系统服务net stop 服务名正常运维关停,不会触发自动重启
重启系统服务net stop 服务名 && net start 服务名重载全部NSSM配置,重置限流计数器
打开系统服务管理器services.msc图形化查看启停状态、启动类型
按名称筛选进程tasklist | findstr 进程名示例:tasklist | findstr javaw-nssm
强制终止指定PID进程taskkill /F /PID 进程ID仅测试自愈使用,业务环境禁止随意执行
查看NSSM服务配置参数nssm.exe get 服务名 配置项校验重启策略、延迟、限流参数是否生效
修改NSSM服务配置参数nssm.exe set 服务名 配置项 值专属修改退出码、重启延时、限流规则

更多推荐