本文最新修改于2025年12月13日
背景
我们写的软件需要调用一个第三方的厂商的硬件,第三方厂商提供了一个 websocket 的服务部署在 windows 系统上,我们的软件通过与这个 websocket 服务通信来调用第三方硬件。所以这个 websocket 程序一定不能挂掉,否则我们的软件也就出问题了。但是事与愿违,这个 websocket 程序经常莫名其妙的挂掉了,经过观察,有可能是写的不好,CPU 占用有时会很高,被系统干掉了。
所以守护这个 websocket 程序是至关重要。
除此之外,我们常常会把jar包部署在客户的windows上,虽然可以直接用cmd启动jar,或者直接写一个bat脚本来启动,但这种方式肯定不如使用windows服务。
windows服务
windows 系统服务的注册可以使用 sc 命令
sc.exe [<servername>] create [<servicename>]
[type= {own | share | kernel | filesys | rec | interact type= {own | share}}]
[start= {boot | system | auto | demand | disabled | delayed-auto}]
[error= {normal | severe | critical | ignore}]
[binpath= <binarypathname>]
[group= <loadordergroup>]
[tag= {yes | no}]
[depend= <dependencies>]
[obj= {<accountname> | <objectname>}]
[displayname= <displayname>]
[password= <password>]
但有两个问题:
1、直接使用 exe 程序创建出来的服务可能不能启动!
如果被封装的 .exe 程序不是原生 Windows 服务(即不支持 Service Control Protocol, SCP),则 SCM 无法与其正常通信,可能导致:
- 服务启动后立即退出;
- SCM 报错:“服务没有及时响应启动或控制请求”(错误 1053)
因此,对于普通 GUI 程序或批处理脚本,直接用 sc create 注册往往不可靠。
2、服务意外退出是不能自动重启的
sc.exe create 命令本身仅负责将服务注册到服务控制管理器(SCM)中,并不自动设置崩溃后的自动恢复行为。
如果服务进程因异常崩溃或被终止,SCM 不会主动重新启动它,服务状态将停留在“已停止”,除非手动干预或系统重启(若为 auto 启动类型)。
要实现“意外退出后自动重启”,需要额外配置服务的 恢复策略(Recovery Policy)。
- 方式1:使用
sc failure命令配置恢复动作 - 方式2:通过服务属性图形界面设置
- 打开
services.msc; - 右键目标服务 → “属性” → “恢复”选项卡;
- 设置“第一次失败”、“第二次失败”、“后续失败”的操作为“重新启动服务”;
- 设置“重置失败计数”为 300 秒(或其他合适值)
- 打开
NSSM
NSSM (Non-Sucking Service Manager)是一款专为Windows系统设计的开源工具,可将普通可执行程序(如exe、批处理脚本、Python/Node.js应用等)注册为系统服务,实现后台静默运行、开机自启动、崩溃自动重启和日志管理等功能。
-
下载 NSSM
-
打开命令提示符
cmd(以管理员身份运行),然后切换至NSSM所在的目录 -
运行
nssm.exe install,会立即弹出一个对话框 -
在弹出的对话框中完成设置,一般来说:
- 设置服务名称
- 选择程序的运行目录
- 选择要运行的程序
- 设置启动命令行参数
- 设置退出重启
- 设置输出重定向到文件(日志)
- 最后点击 install service
-
服务注册完成后,可以通过 windows 上的服务功能中找到,并可以启动;也可以使用
nssm start <服务名>启动服务