NSSM 实战手册:一键将你的脚本与程序部署为 Windows 后台服务
1. NSSMWindows服务管理的瑞士军刀第一次接触NSSM是在五年前的一个运维紧急任务中当时需要将一个Python写的日志分析工具部署成后台服务。这个工具原本是通过计划任务每小时运行一次但经常因为权限问题崩溃。直到同事推荐了NSSM我才发现原来Windows服务管理可以如此简单。NSSM全称Non-Sucking Service Manager直译就是不糟糕的服务管理器。这个略带幽默的名字背后是一个真正解决了Windows服务管理痛点的神器。它最大的特点是可以将任何可执行程序——无论是EXE、BAT脚本还是Python/Ruby等解释型脚本——转化为标准的Windows服务。与Windows自带的sc命令相比NSSM提供了三大杀手级功能图形化配置界面不用记忆复杂的命令行参数自动故障恢复服务崩溃后会自动重启完善的日志记录可以方便地收集服务的标准输出和错误输出在实际工作中我经常用它来部署以下类型的程序用Go/Python/Node.js写的各种工具程序Java的Spring Boot应用虽然官方提供了winsw但配置更复杂Nginx/Redis等没有原生Windows服务支持的开源软件需要长期运行的批处理脚本2. 从零开始安装配置NSSM2.1 获取NSSM的正确姿势虽然NSSM官网(nssm.cc)已经停止更新但2.24版本经过多年实践验证非常稳定。我建议直接从GitHub的release页面下载预编译版本# 64位系统推荐下载 https://github.com/kirillkovalenko/nssm/releases/download/2.24/nssm-2.24.zip下载后解压到任意目录我习惯放在C:\Program Files\nssm下。这里有个小技巧把nssm.exe所在目录加入系统PATH环境变量这样在任何位置都能直接调用nssm命令。2.2 首次运行前的准备NSSM需要管理员权限才能操作系统服务所以无论是命令行还是PowerShell都需要以管理员身份运行。这里分享两个我常用的方法快捷键法WinX → 选择终端(管理员)右键菜单法在资源管理器按住Shift键右键点击文件夹 → 在此处打开PowerShell窗口 → 然后输入Start-Process powershell -Verb runAs注意在Windows 11 22H2之后的版本中默认终端可能不是管理员权限需要特别注意。3. 实战将Python脚本部署为服务3.1 典型场景分析假设我们有一个监控服务器磁盘空间的Python脚本disk_monitor.py它每5分钟检查一次磁盘使用情况超过阈值就发送告警。这个脚本目前是通过计划任务运行的但存在以下问题没有完善的日志记录崩溃后不会自动恢复无法方便地查看运行状态下面我们就用NSSM来解决这些问题。3.2 详细配置步骤首先准备好Python环境我假设Python安装在C:\Python39脚本存放在D:\scripts\disk_monitor.py以管理员身份打开命令行执行nssm install DiskMonitor这时会弹出配置窗口我们需要填写几个关键参数Application标签页Path:C:\Python39\python.exeStartup directory:D:\scriptsArguments:disk_monitor.pyDetails标签页Display name: 磁盘监控服务Description: 监控服务器磁盘空间使用情况Startup type: Automatic (延迟启动)I/O标签页Output (stdout):D:\scripts\logs\disk_monitor.out.logError (stderr):D:\scripts\logs\disk_monitor.err.logLog on标签页 这里有个重要技巧如果脚本需要访问网络资源建议使用此账户选项指定一个有足够权限的域账户或本地账户。点击Install service后服务就创建完成了。可以通过以下命令启动服务nssm start DiskMonitor3.3 常见问题排查在实际部署中我遇到过几个典型问题Python模块导入失败这是因为服务运行时的PYTHONPATH与交互式环境不同。解决方法是在脚本开头显式添加路径import sys sys.path.append(rD:\python_libs)权限问题特别是需要访问网络共享或注册表时。可以在Log on标签页指定有足够权限的账户或者直接使用Local System账户。中文乱码在I/O标签页的Console encoding选择65001 (UTF-8)可以解决大部分编码问题。4. 高级配置技巧4.1 环境变量管理很多程序依赖特定的环境变量NSSM提供了两种设置方式全局环境变量在Environment标签页添加格式为NAMEVALUE启动参数传递在Arguments中添加如--configD:\config\app.ini我建议将敏感信息如数据库密码等放在环境变量中而不是直接写在脚本里。4.2 自动重启策略NSSM的Exit Actions标签页可以配置各种恢复策略第一次失败重启服务第二次失败延迟30秒后重启后续失败执行自定义操作对于关键服务我通常这样配置Throttle: 30000 ms First failure: Restart Service Second failure: Restart Service Subsequent failures: Restart Service Reset fail count after: 60000 ms4.3 服务依赖关系如果服务之间有启动顺序要求可以在Dependencies标签页设置。比如我们的DiskMonitor服务需要等待MySQL服务启动服务依赖项: MySQL5. 日常维护与监控5.1 服务状态检查除了使用nssm status servicename命令外我习惯用PowerShell获取更详细的信息Get-Service DiskMonitor | Select-Object Name,DisplayName,Status,StartType5.2 日志轮转方案NSSM本身不提供日志轮转功能但可以通过以下方式实现使用logrotate for Windows在脚本中实现日志分割使用Windows内置的wevtutil管理事件日志我通常选择第一种方案配置示例D:\scripts\logs\*.log { daily rotate 7 compress missingok notifempty }5.3 批量管理技巧当需要管理多个服务器上的服务时可以编写PowerShell脚本远程执行NSSM命令$servers server1,server2,server3 $command nssm restart DiskMonitor Invoke-Command -ComputerName $servers -ScriptBlock { param($cmd) iex $cmd } -ArgumentList $command6. 真实案例物联网数据采集服务去年我参与了一个工业物联网项目需要在50多台现场设备上部署数据采集服务。这些设备运行Windows 10 IoT系统采集程序是用Go编写的。通过NSSM我们实现了统一的服务部署脚本崩溃自动恢复现场设备经常意外断电集中日志收集关键配置如下Application: D:\collector\data_collector.exe Arguments: --configD:\collector\config.toml Startup: Automatic (Delayed) Recovery: Restart after 1 minute这个项目让我深刻体会到NSSM在边缘计算场景下的价值——它用极小的资源开销每个服务约2MB内存提供了企业级的服务管理能力。