Windows-NSSM通俗易懂介绍,安装与深度实战

Windows 服务化部署指南:NSSM 深度实战

一. 核心环境与学习路径

在开始将应用程序转化为 Windows 服务之前,我们需要锁定本次实战所依赖的核心工具版本,确保我们的操作环境保持一致。NSSM 虽然更新频率不高,但其稳定性在 Windows 运维领域备受推崇。

技术组件版本号说明
Windows OS10 / 11 / Server 2016+64 位 操作系统
NSSM2.24目前最稳定的 Release 版本
.NET Framework4.xNSSM 运行基础依赖 (系统自带)

摘要:本笔记将深入讲解如何在 Windows 环境下,利用 NSSM (The Non-Sucking Service Manager) 将普通的可执行程序(如 .exe, .bat, .jar 等)封装为系统级服务。我们将通过实战解决应用无法开机自启、意外崩溃无法自动恢复以及控制台窗口干扰桌面操作等痛点,最终实现全自动化的服务运维管理。

1.1. 阶段式学习路径

我们把对 NSSM 的掌握分为三个阶段,由浅入深逐步推进:

  1. 基础部署阶段:掌握 NSSM 的安装与配置,通过 GUI 界面完成第一个服务的创建。
  2. 进阶配置阶段:深入理解 I/O 重定向(日志管理)、环境变量配置以及依赖关系处理,解决“服务跑起来但没日志”的问题。
  3. 自动化运维阶段:脱离 GUI,使用纯命令行指令进行批量部署、参数修改和故障恢复设置,建立标准化的部署模版。

二. NSSM 的安装与环境配置

2.1. 获取与安装

NSSM 是一个免安装的绿色软件,但为了在命令行的任何位置都能随时调用它,我们需要进行全局路径配置。

步骤 1:下载组件

注意: 官网太久没有维护了,包括git仓的版本也不再更新,下载链接已经很难找到了,本文使用的是最后一个版本的中文汉化,下载链接如下:

https://prorise-blog.oss-cn-guangzhou.aliyuncs.com/博客文件存储/nssm-win64-Release.zip

步骤 2:规划目录
不要将软件解压在临时目录或包含中文、特殊空格的路径下。我们推荐建立一个统一的工具目录:

1
2
3
4
5
6
C:\Tools\nssm-2.24\
├── win32\
├── win64\
│ └── nssm.exe <-- 我们将使用这个核心文件
└── nssm.h

步骤 3:配置环境变量
为了在 CMD 或 PowerShell 中直接使用 nssm 命令,我们需要将 win64 目录添加到系统的 PATH 中。

  1. 右键点击“此电脑” -> “属性” -> “高级系统设置” -> “环境变量”。
  2. 在“系统变量”区域找到 Path,点击“编辑”。
  3. 新建并填入:D:\NSSM\nssm.exe(这里要根据你实际安装的文件路径来)

2.2. 验证安装

打开一个新的命令提示符窗口(CMD),输入以下命令验证配置是否生效。

1
2
# 查看版本信息
nssm version

如果输出 NSSM 2.25.0 64-bit Nov 11 2025,说明环境配置成功。如果提示“不是内部或外部命令”,请检查路径配置是否正确并在配置后重启 CMD 窗口。


三. 快速上手:BAT 脚本服务化

在上一节中,我们完成了工具的准备。但在实际业务中,我们经常遇到需要开机自动运行一个批处理脚本(.bat)来启动某些监控或清理任务的情况。直接将快捷方式放入“启动”文件夹虽然简单,但存在无法自动重启、运行时有黑窗口等缺陷。

本节我们将通过 GUI 图形化界面,将一个简单的 BAT 脚本转化为 Windows 服务。

3.1. 准备测试脚本

为了模拟真实场景,我们创建一个会持续运行并输出日志的 BAT 脚本。

步骤 1:创建工作目录
D:\NSSM\demo-script 下创建 run.bat 文件。

步骤 2:编写模拟逻辑
这个脚本会每隔 5 秒向控制台输出当前时间,模拟一个长连接服务。

1
2
3
4
5
@echo off
:loop
echo [INFO] Service is running at %date% %time%
timeout /t 5 >nul
goto loop

3.2. 使用 GUI 封装服务

NSSM 提供了非常直观的图形化配置界面。

步骤 1:启动配置界面
管理员身份 运行 CMD,执行以下命令唤起安装窗口:

1
2
# nssm install <自定义服务名称>
nssm install MyScriptService

步骤 2:填写核心参数
弹出的窗口中包含多个标签页,我们首先关注 Application 标签页:

  • Path (程序路径): 选择你的 run.bat 文件。

  • 例如:D:\NSSM\demo-script\run.bat

  • Startup directory (启动目录): NSSM 会自动填充为脚本所在目录。

  • 注意:如果你的脚本中有相对路径操作(如 ./config.ini),此项必须正确指向脚本根目录。

image-20251222165354018

步骤 3:安装服务
点击底部的 Install service 按钮。如果弹出 “Service ‘MyScriptService’ installed successfully!” 提示,说明创建成功。

3.3. 服务的启动与验证

服务安装后默认处于停止状态,我们需要将其启动。

操作命令:

1
2
3
4
5
6
# 启动服务
nssm start MyScriptService

# 查询服务状态
nssm status MyScriptService

预期结果:
状态应显示为 SERVICE_RUNNING。打开 Windows 任务管理器,切换到“服务”选项卡,你也能看到 MyScriptService 正在运行。

注意:此时你通过 CMD 启动了服务,但你不会看到刚才 BAT 脚本中的黑窗口。这是因为服务在后台 Session 0 中运行,这正是我们想要的效果——无干扰运行

3.4. 服务的全生命周期管理

在服务成功运行后,我们必然会面临修改脚本逻辑、暂停服务进行维护,或者彻底移除服务的场景。NSSM 提供了覆盖服务全生命周期的管理命令。

场景 1:服务的停止与重启
当我们需要更新 run.bat 的脚本内容时,必须先停止服务解除文件占用,修改完成后再重启。

1
2
3
4
5
6
# 暂停服务 (发送 Stop 信号)
nssm stop MyScriptService

# 重新启动服务 (加载最新的脚本逻辑)
nssm restart MyScriptService

场景 2:服务的彻底销毁
如果该服务不再需要,我们需要将其从 Windows 服务列表中彻底移除。

方法 A:交互式移除(推荐新手)
执行移除命令,会弹出一个确认窗口,防止误删。

1
nssm remove MyScriptService
  • 系统会弹出确认框:“Are you sure you want to remove the service?”
  • 点击 “Yes” 完成卸载。

方法 B:静默强制移除(适合脚本)
在自动化脚本中,我们不需要弹窗确认。

1
nssm remove MyScriptService confirm

场景 3:服务的状态监测
除了使用 nssm status,我们更推荐使用 Windows 原生命令或 PowerShell 查看更详细的进程信息,确认服务是否“假死”。

1
2
# 查看服务详细 PID 和状态
sc queryex MyScriptService

四. 进阶实战:Java (Spring Boot) 应用的深度配置(可选阅读)

回顾上一节,我们成功部署了一个简单的 BAT 脚本。但在企业级开发中,Java 应用(尤其是 Spring Boot JAR 包)才是服务化的主力军。虽然我们可以像上面一样把 java -jar app.jar 写在 BAT 里再通过 NSSM 启动,但那种方式会导致进程树(Process Tree)复杂化。

本节我们将学习 直接调用 Java 虚拟机 来运行 JAR 包,并重点解决 日志重定向内存参数配置 问题。

mermaid-ai-diagram-2025-12-22-083435

4.1. 部署架构规划

我们将演示部署一个名为 order-service.jar 的应用。

目录结构:

1
2
3
4
D:\services\order-service\
├── order-service.jar # 业务包
├── application.yml # 配置文件
└── logs\ # 日志目录(需提前创建)

4.2. 配置 Application 核心参数

我们不再使用 GUI,而是开始尝试使用命令行进行部分配置,这更符合运维规范,但为了直观,我们先用 GUI 确认参数填写的逻辑。

运行 nssm install OrderService

  1. Path (程序路径): 这里 不要 填 jar 包路径,而是填 Java 运行时的绝对路径。
  • 例如:C:\Program Files\Java\jdk-17\bin\java.exe
  1. Startup directory (启动目录): 填 JAR 包所在的文件夹。
  • 例如:D:\services\order-service
  1. Arguments (运行参数): 这里填写 JVM 参数和 JAR 包路径。
  • 例如:-Xms512m -Xmx1024m -jar order-service.jar --spring.profiles.active=prod
场景标题
2025-12-22 10:00
S

老师,为什么 Path 填 java.exe 而不是 jar 包?

T
teacher

因为 Windows 服务本质上是运行一个可执行程序(exe)。Jar 包只是一个归档文件,它不能自己运行,必须由 JVM(java.exe)来加载和执行。

S

那我以前写 bat 也是调用的 java 命令,有什么区别吗?

T
teacher

区别在于,如果是 NSSM -> java.exe,NSSM 能直接监控 JVM 的死活。如果是 NSSM -> bat -> java.exe,NSSM 监控的是 bat(cmd.exe),如果 Java 进程崩了但 cmd 没关,服务可能就不会自动重启。

4.3. 配置 I/O 重定向(日志管理)

这是新手最容易忽略的一步。服务在后台运行,如果没有配置 I/O 重定向,所有的 System.out.println 和报错堆栈都会丢失。

切换到 I/O 标签页(或使用命令行设置):

  • Output (stdout): 标准输出日志路径。

  • 设置:D:\services\order-service\logs\stdout.log

  • Error (stderr): 错误日志路径。

  • 设置:D:\services\order-service\logs\stderr.log

4.4. 配置 File Rotation (日志轮转)

为了防止日志文件无限增长占满磁盘,NSSM 提供了原生的日志切割功能。切换到 File rotation 标签页:

  1. 勾选 Rotate files
  2. Restrict rotation:
  • File size limit: 例如 10485760 (10MB)。
  • File age limit: 例如 86400 (1 天)。
  1. 此配置意味着:当日志超过 10MB 或跨天时,NSSM 会自动重命名旧日志并创建新日志。

五. 自动化与批量运维

在前面的章节中,我们通过 GUI 完成了配置。但在需要批量部署几十个微服务,或者进行 CI/CD 自动化发布时,鼠标点击显然效率太低。本节我们将展示如何通过纯命令行完成所有操作。

5.1. 命令行安装模版

我们可以将安装过程封装为一个 install.bat 脚本。

步骤 1:编写安装脚本
以下脚本展示了如何通过 nssm installnssm set 命令组合,完成一个复杂 Java 服务的安装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@echo off
set SERVICE_NAME=OrderService
set JAR_PATH=D:\services\order-service
set JAR_NAME=order-service.jar
set JAVA_HOME=C:\Program Files\Java\jdk-17

echo [1/5] Installing service...
nssm install %SERVICE_NAME% "%JAVA_HOME%\bin\java.exe"

echo [2/5] Setting startup directory...
nssm set %SERVICE_NAME% AppDirectory "%JAR_PATH%"

echo [3/5] Setting JVM arguments...
:: 注意:参数中如果包含空格,需谨慎处理引号
nssm set %SERVICE_NAME% AppParameters "-Dfile.encoding=utf-8 -jar %JAR_NAME%"

echo [4/5] Configuring Logging...
nssm set %SERVICE_NAME% AppStdout "%JAR_PATH%\logs\service.out.log"
nssm set %SERVICE_NAME% AppStderr "%JAR_PATH%\logs\service.err.log"
nssm set %SERVICE_NAME% AppRotateFiles 1
nssm set %SERVICE_NAME% AppRotateOnline 1
nssm set %SERVICE_NAME% AppRotateSeconds 86400
nssm set %SERVICE_NAME% AppRotateBytes 10485760

echo [5/5] Starting service...
nssm start %SERVICE_NAME%

echo Done!
pause

5.2. 服务修改与删除

在服务运行期间,如果我们需要修改内存参数或删除服务,可以使用以下命令:

修改配置:
如果你想通过 GUI 修改现有服务:

1
nssm edit OrderService

这会打开刚才的配置界面,修改并保存即可(需重启服务生效)。

删除服务:

1
2
3
4
5
6
7
8
9
# 停止服务
nssm stop OrderService

# 确认删除(会有二次确认弹窗)
nssm remove OrderService

# 强制静默删除(无弹窗,慎用)
nssm remove OrderService confirm

5.3. 常用运维指令速查

命令作用备注
nssm start <name>启动服务
nssm stop <name>停止服务发送终止信号
nssm restart <name>重启服务
nssm status <name>查看状态返回 Running/Paused 等
nssm dump <name>导出配置类似 Docker inspect,打印出创建该服务的所有命令

六. 常见故障排除

在服务化过程中,我们可能会遇到服务无法启动(Paused)或反复重启的情况。

6.1. 服务状态为 “Paused”

现象:执行 nssm start 后,服务状态短暂变为 Running,然后变为 Paused。

原因分析:这通常意味着程序启动后 立刻退出了

  1. 参数错误:例如 Java 路径不对,或 JAR 包损坏。
  2. 目录权限:服务默认以 LocalSystem 账户运行,可能没有访问网络共享目录或特定文件夹的权限。
  3. 批处理陷阱:如果运行 BAT,脚本末尾没有 pause 或死循环,脚本执行完最后一行就会退出,NSSM 检测到进程结束,试图重启,反复多次后进入 Paused 保护状态。

解决方案

  • 检查 AppStderr 指定的错误日志文件。
  • 如果是 BAT 脚本,确保脚本内有阻塞逻辑(如 goto loop)。
  • 检查 AppDirectory 是否正确,Java 应用常因找不到相对路径的配置文件而闪退。

七. 本章总结与实战速查

通过本章的学习,我们不仅掌握了 NSSM 的基本使用,还深入了解了 Java 应用在 Windows 服务化过程中的各种细节配置。

7.1. 核心要点回顾

  1. 架构优势:使用 NSSM -> java.exe 模式比 NSSM -> bat 更稳定,能准确监控进程状态。
  2. 日志生命线:必须配置 AppStdoutAppStderr,否则服务就是黑盒,无法排查问题。
  3. 绝对路径:在服务配置中,尽量使用绝对路径,避免因工作目录(AppDirectory)切换导致的资源加载失败。

7.2. 场景化代码模版

遇到以下 3 种场景时,请直接 Copy 下方模版进行修改:

场景一:最简 Java 服务安装(命令行版)

需求:快速部署一个 Spring Boot Jar,不需要复杂的日志切割。

1
2
3
4
nssm install MyJavaService "C:\jdk-17\bin\java.exe"
nssm set MyJavaService AppDirectory "D:\app"
nssm set MyJavaService AppParameters "-jar app.jar"
nssm start MyJavaService

场景二:Python 脚本服务化

需求:让 Python 脚本在后台常驻运行。

1
2
3
4
5
6
7
8
# 假设已安装 Python 并配置环境变量
nssm install PyWorker "python.exe"
nssm set PyWorker AppDirectory "D:\scripts"
nssm set PyWorker AppParameters "main.py"
# 将输出重定向到文件
nssm set PyWorker AppStdout "D:\scripts\log.txt"
nssm set PyWorker AppStderr "D:\scripts\err.txt"
nssm start PyWorker

场景三:Node.js 服务化

需求:部署一个 Node.js 的 Express/Koa 应用。

1
2
3
4
5
nssm install NodeApp "C:\Program Files\nodejs\node.exe"
nssm set NodeApp AppDirectory "D:\node-project"
nssm set NodeApp AppParameters "index.js"
nssm set NodeApp AppEnvironmentExtra "NODE_ENV=production"
nssm start NodeApp

7.3. 核心避坑指南

  1. 坑点:空格路径
  • 现象:安装时报错或启动失败。
  • 对策:如果路径包含空格(如 Program Files),在命令行模式下必须使用 双引号 包裹整个路径。
  1. 坑点:环境变量读取
  • 现象:服务启动后找不到某些系统环境变量。
  • 对策:Windows 服务运行时使用的是系统账户的环境变量,而非当前登录用户的。如果依赖特定变量,请使用 nssm set <Service> AppEnvironmentExtra "KEY=VALUE" 显式注入。
  1. 坑点:控制台交互
  • 现象:程序需要输入 “Y” 才能继续。
  • 对策:NSSM 运行的服务是非交互式的。必须确保你的程序在启动时不需要任何用户输入(Standard Input),否则程序会挂起。