新闻详情

新闻详情

首页 / 资讯中心 / 详情

NSSM 2.24 实战:把 Spring Boot 服务注册成开机自启的 Windows 服务

发布时间:2026/9/26 23:29:41来源:尧图网络
NSSM 2.24 实战:把 Spring Boot 服务注册成开机自启的 Windows 服务
简介NSSM是一款用于将Spring Boot应用封装为Windows后台服务的轻量级工具特别适合需要快速完成部署的Java开发与运维人员。它无需复杂配置通过选定Java可执行文件、Jar包路径与工作目录即可完成服务注册同时内置日志管理与自动重启机制有助于提升服务稳定性降低异常中断风险直观的操作方式也让非专业人士能够轻松上手。压缩包内共35个文件大小仅344KB包含win32与win64两个平台的nssm.exe可执行程序以及src目录下的源代码其中以h头文件和cpp源文件为主附带ChangeLog与README说明文档便于直接运行、核对更新或按需修改。包内目录结构清晰兼顾实用性与可扩展性。目前已有264人学习下载适合希望在Windows环境下脱离命令行窗口、实现Spring Boot应用后台常驻的开发者参考使用也可作为学习服务封装原理的极简范例。1. 把 Spring Boot 挂成 Windows 服务NSSM 2.24 为什么是首选你有没有遇到过这种场景Spring Boot 的 jar 包在 Windows 服务器上已经能正常用java -jar跑起来但只要关掉那个命令行窗口服务立刻死给你看用任务计划程序挂一个开机启动又发现进程是起来了可一旦崩溃没人管日志也散落在黑洞里。第一次部署上线的人多半在这个环节折腾大半天最后不是补了开机脚本继续忍受窗口常驻就是被sc.exe的退出码折腾到怀疑人生。NSSM 2.24 就是来解决这个问题的这个压缩包解压后只有一个nssm.exe全称 Non-Sucking Service Manager中文语境里就是不折腾服务管理器。它把你的 jar、Python 脚本、任何控制台程序包装成真正注册到 Windows 服务控制管理器里的服务支持崩溃自动重启、离线日志滚动、开机自启、环境变量注入。本文我就是拆这个包、配 Spring Boot 生命周期把参数含义和翻车点一次说透。2. NSSM 的注册与进程管理机制它凭什么能管住 java 进程2.1 先对比sc.exe、WinSW、srvany 各自卡在哪Windows 自带的服务创建工具是sc.exe它能sc create一个服务指定 binPath 指向可执行文件。直接拿它创建 Spring Boot 服务会碰到两个问题第一sc.exe创建的进程默认由服务控制管理器SCM接管但服务的可执行路径要写在命令里等 Spring Boot 进程一退出服务直接进入 Stopped 状态没有任何自动重启策略第二Spring Boot 的java.exe没有服务生命周期协议SCM 发送停止信号时依赖ExitCode判断可普通控制台进程常常退不干净。WinSW 是 GitHub 上一个开源方案配置文件是 XML启动停止靠自身封装进程。它的特点是功能丰富但对环境有要求WinSW 需要 .NET Framework 运行时。你在干净机房环境部署时还要先确认系统是否带着对应版本的 .NET否则服务管理进程先崩了。srvany 是从 Windows Resource Kit 里活下来的老古董它把任意程序塞进服务壳子配置藏在注册表里AppDirectory、AppParameters都要手动写路径一有空格就玄学失败而且没有自动重启模块。相比之下 NSSM 2.24 是单文件绿色绿灯GUI 和命令行双控把 Java 服务的启动目录、参数、日志、退出处理全部收拢在一套配置里这也是我最终选择它的原因。2.2 NSSM 的进程模型子进程包装与优雅停止NSSM 在工作时把自己注册成 SCM 眼中的服务主体它再去 fork 出真实的 java 进程。也就是说服务控制管理器看到的是nssm.exe而nssm.exe以子进程方式运行你的java.exe或javaw.exe。这样一来SCM 对服务状收敛的管理全部作用在 NSSM 上NSSM 再根据你的配置决定怎么处理 java 进程。停止服务时NSSM 默认会做一套完整的先君子后小人流程先给 java 主线程发 CtrlC 信号等 AppStopMethod 里配置的宽限时间默认 5 秒让 Spring Boot 走完优雅停机逻辑如果没退出再尝试发送 WM_CLOSE 消息再不行它直接调用TerminateProcess强制结束进程树。这就是为什么你从服务管理器里停止服务时Spring Boot 的PreDestroy回调有机会执行数据库连接池能正常回收。反观sc stop直接对裸 java 进程下手大概率就是强杀磁盘上容易留下半截数据。NSSM 的配置数据落在注册表HKLM\SYSTEM\CurrentControlSet\Services\服务名\Parameters下面参数名是以App开头的键值。你用 GUI 填的一次配置本质就是写这一堆注册表键所以nssm edit和regedit手工改效果是一致的。如果要批量分发服务器我会写一个 bat 脚本用命令行配置避免每次折腾 GUI。2.3 核心参数速查先记住这几个键NSSM 2.24 参数很多但日常 Spring Boot 服务用到的就这几类建议收藏对照参数作用Spring Boot 场景下怎么设Application可执行程序路径指向 JDK 的 java.exe 绝对路径AppDirectory进程工作目录你的 jar 包所在目录别写错SSH 里的相对路径问题全在这AppParameters传给程序的命令行参数-jar D:\app\server.jar --server.port8080AppEnvironment附加环境变量设置SPRING_PROFILES_ACTIVEprod之类AppStdout / AppStderrstdout/stderr 重定向文件指向日志目录的绝对路径文件AppRotateFiles日志滚动开关1 表示开配合 AppRotateBytesAppRotateBytes单日志文件大小阈值单位字节生产上配 10485760 即 10MBAppExit退出码处理策略默认值 Restart意思是不管什么退出码自动重启AppStopMethod停止方式默认 5000 毫秒等 CtrlC够用从表里也能看出它的设计取向所有跟进程相关的配置都是显式的不依赖当前用户环境变量。很多新手把Application填成java结果服务启动失败原因就是服务进程上下文里没有 PATH 环境变量NSSM 可不会替你走 shell 做命令解析。3. 完整落地把 java -jar 注册成可自启的服务3.1 准备工作文件与路径规划下载 nssm-2.24.zip 解压后根据系统架构选择win64/nssm.exe或win32/nssm.exe。第一步别急着双击先把 exe 放到固定目录比如C:\nssm\nssm.exe再把它加入 PATH。把这个 exe 放在部署脚本能找到的稳定位置原因是服务注册后SCM 的路径会一直引用这个 exe如果你把它放下载文件夹后来清理了服务会直接起不来。在此期间先把 Spring Boot 的 jar 包放到D:\app\server.jar并确认 JDK 路径。NSSM 的垃圾桶机制是服务启动失败时它先看Application是否存在不存在就会把服务标记为失败并写事件日志。我一般会把 JDK 路径用绝对路径写死比如C:\Program Files\Java\jdk1.8.0_291\bin\java.exe避免服务器上装有多个 JDK 时被 PATH 指向奇怪版本。3.2 GUI 安装nssm install 弹出的窗口怎么填在管理员权限的命令提示符里执行C:\nssm\nssm.exe install demo-server输入服务名后会弹出一个图形界面核心选项卡有三个I/O 选项卡我们先放着。Application 选项卡里Path 填C:\Program Files\Java\jdk1.8.0_291\bin\java.exe注意直接填可执行文件本身Startup directory 填D:\app这是 java 的工作目录Spring Boot 读取application.yml时相对路径是基于这里计算的Arguments 填-jar D:\app\server.jar --server.port8080多个参数用空格分隔如果参数本身带引号外层引号要保留。接着切换到 Details 选项卡Display name 可以填Spring Boot Demo ServerDescription 填后台运行 spring boot web 服务Startup type 在下拉框里选 Automatic意思是开机自动启动。这里填完点 Install service 按钮GUI 会在底部提示服务安装成功。之后去服务管理器里找到这个服务名手动启动第一次启动一定要观察状态是否变成 Running如果秒变 Stopped说明参数写错了基本就在 Path 或 Arguments 的拼接细节上。3.3 命令行安装我把这套部署脚本贴在下面GUI 适合本地临时调试一台机器生产环境批量部署我会用命令行思路是把 write log 和 set 命令写成一个 bat。下面的脚本在一个有管理员权限的 cmd 里执行nssm install demo-server C:\Program Files\Java\jdk1.8.0_291\bin\java.exe -jar D:\app\server.jar --server.port8080 nssm set demo-server AppDirectory D:\app nssm set demo-server DisplayName Spring Boot Demo Server nssm set demo-server Description Spring Boot 后台服务 nssm set demo-server Start SERVICE_AUTO_START nssm set demo-server AppExit Default Restart nssm set demo-server AppRotateFiles 1 nssm set demo-server AppRotateBytes 10485760 nssm start demo-server第一行nssm install的参数格式是服务名、Application、AppParameters 三要素包在引号里的参数会被完整当做一个字符串。这里有个细节install后直接跟应用路径和参数中间不要额外加等号nssm set则以键值对方式修改配置两者混搭时后执行的 set 会覆盖前面 install 写入的重合键。所以我特意把AppDirectory单独 set 一遍目的是确保工作目录和 jar 包目录一致防止 Spring Boot 的相对路径找不到配置文件。AppEnvironment 的配置在用命令行时有特殊语法比如注入 Spring Boot 的 profilenssm set demo-server AppEnvironment SPRING_PROFILES_ACTIVEprod JAVA_OPTS-Xms256m -Xmx512m注意AppEnvironment的多个变量是每个都用引号包住空格分隔等号两边不要乱加空格。注册完之后nssm start demo-server就是拉起服务一切正常的话命令会返回Start: SERVICE_RUNNING字样。3.4 生产参数调整让 Spring Boot 服务更像正式服务生产环境第一要务是限制 JVM 堆内存我习惯把 JVM 参数直接塞进AppParameters而不是 AppEnvironment。原因在于java -jar的 JVM 参数必须出现在-jar之前如果写进环境变量里NSSM 的进程上下文不会自动拼接。正确写法是把整个 java 命令的参数拍平nssm set demo-server AppParameters -Xms256m -Xmx512m -jar D:\app\server.jar --server.port8080 --spring.profiles.activeprod另一个生产参数是服务恢复策略。默认AppExit Default Restart对任何退出码都触发重启但如果你的 Spring Boot 因为配置错误启动即死重启也是无限白给。我一般会配合 Windows 服务本身的 recovery 设置做限制或者先人工确认能启动再把它设成自动模式。服务启动方式可以随时从SERVICE_AUTO_START改成SERVICE_DEMAND_START手动这样测试阶段不会开机自己乱拉。4. 避坑NSSM 2.24 实战最容易翻车的五个场景4.1 服务启动后立刻停止事件日志报 ERROR 1067现象执行nssm start demo-server命令提示符显示启动失败服务状态在服务管理器里一闪就回到已停止Windows 事件查看器显示错误 1067 进程意外终止。原因最常见的不是 NSSM 坏了而是 Application 或 AppParameters 的拼接启动后进程在几秒内就崩溃退出。要么是 java.exe 路径写错比如填成了jdk目录而不是bin\java.exe要么是-jar前面多了一个换行或空格导致解析错误。NSSM 不会帮你拼路径它只会把字符串原样穿给 CreateProcess。解决先做一次裸跑验证。在 cmd 里手动执行完整命令确认 spring boot 能起来再关掉。之后用nssm edit demo-server打开 GUIApplication 选项卡里把 Path 和 Arguments 完整检查一遍或者直接看注册表reg query HKLM\SYSTEM\CurrentControlSet\Services\demo-server\Parameters确认 ImagePath 和 AppParameters 的存储值与预期一致。我赌大概一半的人问题出在-jar前面没有空格cmd 把...java.exe-jar当成一个不存在的文件执行了。4.2 服务显示 Running但 javaw 进程就是不存在现象nssm start后列表显示 RUNNING但任务管理器里找不到 java 相关进程Spring Boot 端口也没监听。原因NSSM 的默认AppExit是 Restart假如 java 启动后因为端口占用立刻退出NSSM 会紧跟着再次拉起在循环重启的空隙里服务状态停留在 Running。这是典型的服务壳活着应用进程死了。解决观察 NSSM 的AppStderr日志文件Spring Boot 启动报错会写在 stderr 里。修好底层问题之前可以把AppExit暂时设成Exit不重启逼着服务失败暴露真因。命令是nssm set demo-server AppExit Default Exit等它成功跑起来了再改回Restart。还有个容易忽视的信息源是nssm status demo-server它会返回进程 PID顺手tasklist /FI PID eq pid就能确认进程是否真实存在。4.3 路径带空格Program Files 的引号地狱现象注册服务后启动失败事件 ID 7009 提示找不到指定路径或模块但 cmd 里跑同样命令是好的。原因NSSM 解析 Application 路径和启动参数有自己的一套规则它不像 shell 那样做分词。路径里有空格并且引号放在最外层NSSM 可能把C:\Program Files切开导致找到的是C:\Program。命令行参数里的引号也会在注册表转义过程中被吃掉最后 java 收到的是一个残缺路径。解决能不用空格路径就不用。如果你的 JDK 装在带空格目录里两层保险第一在 GUI 的 Path 里手动浏览选中java.exe让 NSSM 自动生成转义后的路径第二改用 8.3 短路径。在 cmd 里执行dir /x C:\Program Files\Java能看到短名称形如C:\PROGRA~1\Java把它填到 Application 里从根上避开空格。Arguments 里的 jar 包路径也同理尽量放到D:\app这类无空格的目录。我自己的习惯是Java 服务目录永远不放Program Files这不是教条纯粹是被引号坑怕了。4.4 服务设成开机自启重启后却没起来现象Startup type 选了 Automatic也看到服务在列表里。但系统重启后服务状态是空白的没有自动 Running。原因一般有两种情况。第一种是服务以指定账户身份运行那个账户的密码过期或输入错误SCM 加载时无法取得账户令牌服务直接进 Recovery 等待。第二种是服务依赖的网络共享目录还没就绪比如 jar 包放在别的机器上开机瞬间网络栈没起来java 进程找不到 jar服务启动失败后续又没有 recovery 再试就停留在 Failed 状态。解决Spring Boot 服务没有特别权限需求的话用 LocalSystem 账户运行最省事即nssm set demo-server ObjectName LocalSystem。如果想用自建账户在服务属性登录标签里把密码重新填一遍别依赖 GUI 的可交互勾选。依赖网络共享的路径直接放弃把 jar 部署到本机磁盘。另外给服务管理器设置恢复规则失败后延迟 5 分钟自动重启一次能避开典型的依赖还没起来窗口。这个设置用命令行sc failure demo-server reset 86400 actions restart/60000/restart/120000/restart/300000它的含义是失败后等待 60 秒第一次重启再失败等 120 秒第三次起等 300 秒24 小时内连续失败能得到一个延迟退避的效果。4.5 替换 jar 后重启服务运行的还是老版本现象停掉服务覆盖server.jar为新包再启动服务访问接口还是老逻辑连日志输出的启动时间戳都没变。原因NSSM 默认停止服务时只给主进程发 CtrlC但 Spring Boot 有时候会有自己的非守护线程没被停止信号处理干净JVM 进程实际上还挂在后台。此时替换 jar 文件旧进程仍然占用着 jar 文件句柄磁盘上的新 jar 根本无法写入。即使覆盖成功Windows 下一部分场景允许替换再启动时 NSSM 也只是把新进程 fork 出来文件系统缓存可能让它读到了旧字节。解决替换前确认 java 进程彻底结束。用nssm stop demo-server之后再tasklist /FI IMAGENAME eq java.exe检查残留有残留就taskkill /F /PID pid强杀。我自己的部署脚本里加了这样一段taskkill /F /FI WINDOWTITLE eq demo-server* taskkill /F /PID pid或者更彻底用nssm remove demo-server confirm先拆除服务替换完 jar 再重新nssm install。别嫌麻烦NSSM 装服务本身只要一秒钟生产环境省掉一次上线后发现还是老代码的事故比什么都值。5. 日志滚动、依赖顺序与状态监控把服务拉进运维体系5.1 日志滚动配置防止单文件把磁盘写满Spring Boot 默认日志在控制台注册成服务后控制台不存在了NSSM 的 stdout/stderr 重定向就成了救命稻草。配置完后日志全写到AppStdout指定的文件里。但 Linux 工程师习惯了 logrotate 的按天切割Windows 上 NSSM 也有类似机制只是它是按大小切nssm set demo-server AppStdout D:\app\logs\server-out.log nssm set demo-server AppStderr D:\app\logs\server-err.log nssm set demo-server AppRotateFiles 1 nssm set demo-server AppRotateBytes 10485760 nssm set demo-server AppRotateOnline 1AppRotateFiles 1打开滚动开关NSSM 在写入日志超过AppRotateBytes指定值这里是 10MB时把当前日志重命名为server-out-时间戳.log并新建一个空文件。AppRotateOnline 1表示无需重启服务即可滚动这个很关键——日志文件被 java 进程句柄占用时你要重启服务才能切文件而 Online 模式下 NSSM 通过复制和截断操作绕开了这个限制。需要提醒的是这套滚动只针对 stdout/stderr 的重定向文件。如果你在 Spring Boot 的application.yml里配置了logging.file.name那么日志由 Logback 直接写文件根本不经过 stdoutNSSM 的滚动对它无效。生产上我会二选一要么让 java 日志只走 console由 NSSM 统一滚动要么只依赖 Spring Boot 自己的日志按天滚动NSSM 的重定向文件只记录启动异常。混用会导致你看着两个日志文件困惑。5.2 开机自启与服务依赖排序把Start设为SERVICE_AUTO_START以后服务会在系统启动阶段由 SCM 拉起不需要登录桌面。但如果同一台机器还跑了 MySQL 或 RedisSpring Boot 启动时连不上数据库会进行多次重试然后失败退出。NSSM 有个DependOnService参数可以让服务管理器保证依赖服务先启动nssm set demo-server DependOnService MySQLWindows 服务名不一定是显示名执行sc query | findstr /i mysql看看真正的服务名再填。多个依赖用分隔符隔开NSSM 的文档支持的语法是DependOnService 依赖服务1 依赖服务2。这样注册后服务管理器里能看到依赖关系开机会严格按拓扑启动。延时启动也是一个应对方案sc config demo-server start delayed-auto让服务等普通自动启动服务跑完一个阶段后再说。如果业务允许我一般设置delayed-auto而不是普通 auto实测对 Spring Boot 这种依赖外部中间件的服务显著提高了开机成功率。5.3 状态巡检用 nssm status 配合定时任务服务挂掉后 NSSM 会自动重启但用户想要的是知道它什么时候挂过。这时候用nssm status主动巡检nssm status demo-server返回SERVICE_RUNNING或SERVICE_STOPPED通过errorlevel判断当前状态。把下面这段塞进计划任务每 5 分钟跑一次echo off nssm status demo-server | findstr /C:SERVICE_RUNNING nul || ( echo %date% %time% service is down D:\app\logs\watchdog.log net start demo-server )逻辑是如果 status 输出里没有SERVICE_RUNNING字样说明服务挂了写一条异常日志再尝试net start拉起。注意NSSM 本身有自动重启这里拉起的场景是服务被 SCM 标记为停止、但 NSSM 的自动恢复策略没生效的极端情况。用这个脚本做兜底比你每天看服务管理器窗口可靠得多。6. 验证运行状态与后续维护三个小动作让服务更可控服务跑起来后建议依次做三次验证而不是看一眼绿色正在运行就收工。第一次验证进程sc queryex demo-server返回的 PID 和tasklist里的 java 进程 PID 对应得上第二次验证端口netstat -ano | findstr 8080能看到监听进程的 PID 是不是同一个第三次验证日志访问一个接口后确认server-out.log里有 Spring Boot 的访问日志输出。三步全过才算真正注册成功。后续日常维护用两个命令就够了nssm edit demo-server改参数然后nssm restart demo-server让改动生效。之前说的注册表方式也可行但改完注册表要重启服务才能加载不如 edit 顺手。还有一个习惯我想强调每次修改配置前把现有配置导出到 reg 文件再动手。reg export HKLM\SYSTEM\CurrentControlSet\Services\demo-server D:\backup\demo-server.reg这样万一新参数把服务搞挂了直接reg import一份旧配置服务恢复到改动前的状态。我在很多服务器上踩过改了个参数就再也起不来的坑回头看最有效的后悔药就是这一行备份命令。从那以后我每装一个 Windows 服务都会强制走一遍先裸跑确认、再注册、再验证端口、最后备份参数的流程不管时间多赶都不跳过。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

JSP+Servlet商城系统全解析:从数据库设计到部署避坑指南 2026/9/27 0:34:19

JSP+Servlet商城系统全解析:从数据库设计到部署避坑指南

简介:面向毕业设计场景的Java Web家用电器购物商城系统,基于JSP、Servlet、JDBC搭建,配套MySQL数据库,适合需要快速掌握传统Java Web开发全流程的本科生或开发者。系统围绕管理员和用户双角色设计:管理员可维护商品信息…

阅读更多 →
Screenbox:Windows 11上开源免费又现代的视频播放器推荐 2026/9/27 0:34:19

Screenbox:Windows 11上开源免费又现代的视频播放器推荐

说实话,在Windows上找播放器这件事,我一直觉得比找视频本身还折腾。系统自带的Windows Media Player早就不更新了,界面停留在上一个时代;MPC-HC停更多年后全靠社区复活;PotPlayer是挺好用但官方渠道夹带私货这事儿让很…

阅读更多 →
JSON Schema实战:Python接口数据契约与防错指南 2026/9/27 0:34:12

JSON Schema实战:Python接口数据契约与防错指南

1. 为什么你写的 JSON 总是“一改就崩”,而别人的数据接口稳如磐石?你有没有过这种经历:前端同事发来一个 JSON 示例,说“照这个结构写后端返回就行”;你吭哧吭哧写完,本地测试全绿,一上线就被前…

阅读更多 →
Agent Substrate与gRPC在Kubernetes中的协同实践 2026/9/27 0:34:12

Agent Substrate与gRPC在Kubernetes中的协同实践

我无法根据当前输入生成符合要求的博文。原因如下:项目标题仅为单个字母“ax”,无明确语义指向;项目正文为空;关键词为空;摘要描述为空;虽提供了部分热搜词(如AX、Agent Substrate、Kubernetes、…

阅读更多 →
ax:面向智能体的轻量级Agent运行时新范式 2026/9/27 0:34:06

ax:面向智能体的轻量级Agent运行时新范式

1. “ax”不是拼写错误,而是正在悄然崛起的Agent运行时新范式最近在几个开源社区和Kubernetes技术分享会上,我反复听到一个看似极简、甚至像打字失误的词——“ax”。它既不是缩写,也不是项目代号的随意截取,而是一个正在被越来越…

阅读更多 →
搞定wordpress菜单路径的5个图解步骤及费用拆解 2026/9/27 0:33:53

搞定wordpress菜单路径的5个图解步骤及费用拆解

搞定wordpress菜单路径的5个图解步骤及费用拆解 别再说模板网站太丑不够用了,那是你没搞懂背后的逻辑。很多甲方拿着几百块的模板站来找我,问我为什么客户留不住、转化率低,我一看后台,菜单路径乱成一锅粥,点击率稀烂。今天我就把…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉