将Spring Boot项目部署为Windows服务,并设置开机
![](https://img.haomeiwen.com/i1899015/fa7ba14597303823.png)
背景
最近基于微服务的思想,使用Spring Boot开发了一个产品。产品开发完成,一开始部署的时候,采用的就是jar包的形式。这种形式存在两个缺点:一是服务启动后DOS窗口一直处于打开状态,二是不能开机启动。产品经理不能接受这种形式,要求注册成Windows服务。
我的环境
Spring Boot 2.1.7.RELEASE
JDK1.8
Win10
寻找解决方案
sc create
sc create 英文|拼音服务名称 binpath= "要注册成windows服务的jar全路径" start= auto
这种方式可以注册成windows服务,但是不能正常启动,会报一种1053的错误
![](https://img.haomeiwen.com/i5781463/c797a26398e59831.png)
研究了好长时间,终究是没有解决,只好另谋它路。
procrun
procrun是apache的一个开源的将jar注册成windows服务的小工具,试了试,因为不能指定spring boot jar包的运行时配置文件即--spring.config.location=application.properties,只能作罢。
winsw
下载:https://github.com/kohsuke/winsw/releases
winsw是一个可以将任何应用程序注册成服务的软件,使用方法如下:
1、将Git Hub中下载的WinSW.NET4.exe和sample-minimal.xml文件及springboot项目的jar包放在同一个文件夹中。
![](https://img.haomeiwen.com/i8707389/63021311de85b6e0.png)
2、需要将winsw执行程序跟xml改成同样的名字,推荐使用项目名+Service的命名方式,比如:WinSW.NET4.exe改成myProjectService.exe,sample-minmal.xml改成myProjectService.xml。
![](https://img.haomeiwen.com/i8707389/4dda5b372c6c3287.png)
3、编辑myProjectService.xml文件,内容如下
<service>
<!--安装成Windows服务后的服务名-->
<id>xx</id>
<!--显示的服务名称-->
<name>xx</name>
<!--对服务的描述-->
<description>This service runs xx project.</description>
<!--这里写java的路径,如何配置了环境变量直接写"java"就行-->
<executable>java</executable>
<!--Xmx256m 代表堆内存最大值为256MB -jar后面的是项目名-->
<arguments>-Xmx256m -jar "xx.jar" [附加参数]</arguments>
<!-- 开机启动 -->
<startmode>Automatic</startmode>
<!--日志模式-->
<logmode>rotate</logmode>
</service>
我的配置文件是这样的
<?xml version="1.0" encoding="UTF-8"?>
<service>
<id>spring-boot-publish-web</id>
<name>spring-boot-publish-web</name>
<description>spring-boot-publish-web 打包demo</description>
<executable>java</executable>
<arguments>-Xms1024m -Xmx2048m -jar ../../boot/spring-boot-publish-web.jar --spring.config.location=../../config/</arguments>
<logmode>rotate</logmode>
<workingdirectory>%BASE%\</workingdirectory>
<logpath>c:\opt\logs\spring-boot-publish-web</logpath>
</service>
4、编辑bat快捷可执行文件
# install安装windows服务
@echo off
set project=spring-boot-publish-web
%~dp0%project%.exe install
echo The %project% service current state:
%~dp0%project%.exe status
pause
# 使用start命令启动服务
@echo off
set project=spring-boot-publish-web
%~dp0%project%.exe start
echo The %project% service current state:
%~dp0%project%.exe status
pause
# 使用uninstall命令卸载服务;
@echo off
set project=spring-boot-publish-web
%~dp0%project%.exe uninstall
echo The %project% service current state:
%~dp0%project%.exe status
pause
# 使用stop命令停止服务
@echo off
set project=spring-boot-publish-web
%~dp0%project%.exe stop
echo The %project% service current state:
%~dp0%project%.exe status
pause
# 使用restart命令停止服务;
@echo off
set project=spring-boot-publish-web
%~dp0%project%.exe restart
echo The %project% service current state:
%~dp0%project%.exe status
pause
# 使用status命令查看当前服务的状态;
@echo off
set project=spring-boot-publish-web
%~dp0%project%.exe status
pause
NSSM
下载:https://nssm.cc/
winsw虽然能够解决我的需求,但是毕竟需要在目标机器上安装.NET framework,且目标机器环境各异,给实施人员增加了难度,有点小题大做了。
随后有找到了NSSM。
把下面的代码copy到一个bat文件中并进行响应的更改,同时保持nssm.exe与bat在统一目录下。
nssm install 英文服务名 JAVA_HOME\bin\java.exe
nssm set 英文服务名 AppParameters -jar spring boot jar --spring.config.location=使用的配置文件路径 -secret redacted
nssm set 英文服务名 AppDirectory %cd%\bin\edu-core-service
nssm set 英文服务名 AppStdout 输出日子路径\log.log
nssm set 英文服务名 AppStderr 错误日志路径\err.log
nssm set 英文服务名 AppStopMethodSkip 6
nssm set 英文服务名 AppStopMethodConsole 1000
nssm set 英文服务名 AppThrottle 5000
nssm start 英文服务名
总结
最后在尝试了多种方案的失败之后,终于找到了可以解决我的需求的方案NSSM。其他的方案可能也能将jar注册成windows服务,只是不适合我的需求而已。