SpringBoot注册Windows服务和启动报错的原因

2次阅读

共计 2716 个字符,预计需要花费 7 分钟才能阅读完成。

SpringBoot 注册 Windows 服务和启动报错的原因
Windows 系统启动 Java 程序会弹出黑窗口。黑窗口有几点不好。首先它不美观;其次容易误点导致程序关闭;但最让我匪夷所思的是:将鼠标光标选中黑窗口日志信息,程序竟然不会继续执行,日志也不会继续输出。从而导致页面一直处于请求状态。回车后程序才能正常执行。同时客户希望我们能部署在 Windows 系统上并且做到开机自动启动。针对以上需求将系统程序注册成 Windows 服务变得尤为重要。
针对于 SpringBoot 程序,目前主流的方法是采用 winsw,简单方便。可是在开发过程中,针对不同的系统,启动服务可能会出现意想不到的结果。同样的配置方法,在 win10 可以成功注册并启动服务。而在 windows server 2012 却启动失败。这里分享我的经验。
注册 windows 服务
制作流程
winsw 是⼀款可以将可执⾏程序安装成 Windows Service 的开源⼩⼯具,官⽹地址, 下载地址制作步骤:第一步:将 springboot 项目打包成 MyServer.jar
第二步:将下载的 WinSW.NET2.exe 改名为 MyServer.exe
第三步:将下载的 sample-minimal.xml 改名为 MyServer.xml
第四步:注册和启动服务
这里重点介绍 sample-minimal.xml 文件
<service>
<!– Windows 服务唯一标识 ID–>
<id>My Server</id>
<!– Windows 服务名称 –>
<name>My Server</name>
<!– Windows 服务描述 –>
<description>This service is a service cratead from a minimal configuration</description>
<!– 启动的可执行文件的路径,如果已经配置环境变量,则不必写全路径(则其实是一个坑)–>
<executable>java</executable>
<arguments> -jar MyServer.jar –spring.datasource.url=jdbc:mysql://localhost:3306/database </arguments>
<!– 日志路径,若目录不存在,则默认为配置文件所在的同一目录 –>
<logpath>ServerPath\log\dashboard\</logpath>
<!– 日志模式,默认为 append 追加模型,rotate 为旋转模式 –>
<logmode>rotate</logmode>
</service>
executable:启动可执行文件的全路径,如果配置环境变量,则可以简写,所有这里填写 Java
arguments:命令执行的参数
logpath:配置日志路径
logmode:日志输出模式,默认为 append,官方文档

append(追加模式)其特点是将日志文件全部输出在一个文件中,这个文件可能会越来越大。
rotate(旋转模式,推荐)当日志文件大小达到 10 兆(默认值),winsw 会将日志重新输出到另外一份日志文件,最多保留 8 个(默认值)。
reset(重置模式)每次重启服务都会重置日志文件。
none(忽略模式)几乎不会生成日志文件。

winsw 常用命令

MyServer.exe install:安装服务
MyServer.exe uninstall:删除服务
MyServer.exe start:启动服务
MyServer.exe stop:停⽌服务
MyServer.exe restart:重启服务
MyServer.exe status:输出当前服务的状态

MyServer.exe 是 WinSW.NET2.exe 文件。在 win10 系统上一次成功,没有多余的烦恼。可生活哪有这么容易,在 windows server 2012 r2 的系统上启动失败。有错误不可怕,可怕的是不会找错误日志。

启动 windows 服务失败
服务启动成功后自动关闭,配置的日志文件也没有生成。尝试用 cmd 执行 java -jar 的命令,服务可以正常启动。但可具体是什么错误却不得而知。其实 Windows 服务是有日志管理的。选择:控制面板 — 管理工具 — 事件查看器 —window 日志 — 应用程序 — 找出对应服务的日志。如下:
Service cannot be started.
System.ComponentModel.Win32Exception: The system cannot find the file specified
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
at winsw.WrapperService.StartProcess(Process processToStart, String arguments, String executable)
at winsw.WrapperService.OnStart(String[] _)
at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object state)
提示很清楚,系统没有找到指定文件,而在 winsw 的 xml 文件中就已经配置了 executable,并且配置了环境变量。那为什么还提示文件没有找到?抱着试一试的心态,将 java 改为了全路径。重新注册服务并启动,结果服务启动成功了。一肚子的火不知道往那撒。
为了避免这种事情再次发生,决定将 executable 的内容设置成 Java 的全路径,于是简单写了一个 bat 文件。
@echo off
# 获取 java 环境变量
set JAVA_HOME=%JAVA_HOME%
echo %JAVA_HOME%
# 替换 java 路径
setlocal enabledelayedexpansion
set file=%cd%\MyServer.xml
set file_tmp=%cd%\MyServer_tmp.xml
set source=JAVAHOME
set replaced=%JAVA_HOME%\bin\java

for /f “delims=” %%i in (%file%) do (
set str=%%i
set “str=!str:%source%=%replaced%!”
echo !str!>>%file_tmp%
)
move “%file_tmp%” “%file%”
# 注册并启动服务
MyServer.exe uninstall
MyServer.exe install
MyServer.exe start
EXIT

正文完
 0