Spring Boot jar 作为 window 服务

Springboot jar as window service

我正在尝试 运行 springboot jar 作为 window 服务,我能够使用下面的脚本来完成。 它生成两个进程 prunsrv.exe 和 java.exe。 但是在停止服务时它只会停止 prunsrv.exe(using //SS//Myservice) 但我可以看到 java.exe 进程仍在 运行ning 我必须只使用任务管理器结束。 如何一次停止这两个进程,这样我就不必在任务管理器中搜索进程来终止?

set "CLASSPATH=D:\temp-1.0.0.jar"

prunsrv.exe //IS//%SERVICE_NAME% ^
    --Description "Myservice" ^
    --DisplayName "%DISPLAYNAME%" ^
    --Install "%EXECUTABLE%" ^
    --LogPath "D:\MyService" ^
    --Startup auto ^
    --StdOutput auto ^
    --StdError auto ^
    --Classpath "%CLASSPATH%" ^
    --Jvm "%JVM%" ^
    --StartImage "%JAVA_HOME%\bin\java.exe" ^
    --StartMethod start ^
    --StopMethod stop ^
    --StartMode exe ^
    --StopMode java ^
    --StartPath "D:\MyService" ^
    --StopPath "D:\MyService" ^
    --StartClass com.darth.MyService ^
    --StopClass com.darth.MyService ^
    --StartParams -jar#%CLASSPATH% ^
    --StopParams stop ^
    --JvmMs 1024 ^
    --JvmMx 6144 

Java 模式下使用 Procrun 几乎肯定行不通:

When using the Java or exe modes, the Procrun service application (prunsrv) launches the target application in a separate process. The "stop" application needs to communicate somehow with the "start" application to tell it to stop. For example, using RPC.

(来源 Procrun documentation)。

停止服务的最简单方法是使用 jvm 模式,在这种情况下 Procrun 会启动 JVM 本身并可以调用带有参数的任意静态方法 String[] 在同一个 JVM 中关闭它。例如。您可以像这样修改您的应用程序:

@SpringBootApplication
public class MyService extends SpringBootServletInitializer {

    public static void main(String[] args) {
        String command = "start";
        if (args.length > 0) {
            command = args[args.length - 1];
        }
        switch (command) {
            case "start":
                SpringApplication.run(Application.class, args);
                break;
            case "stop":
                System.exit(0);
                break;
            default:
        }
    }

}

并像这样安装它:

prunsrv.exe //IS//MyService ^
    --Description "MyService" ^
    --Startup auto ^
    --Classpath "D:\temp-1.0.0.jar" ^
    --StartMode jvm ^
    --StartClass org.springframework.boot.loader.JarLauncher ^
    --StopMode jvm ^
    --StopClass org.springframework.boot.loader.JarLauncher ^
    --StopParams stop ^
    --LogPath "D:\MyService" ^
    --LogLevel Debug ^
    --StdOutput auto ^
    --StdError auto

备选方案

Procrun 的一个未记录的功能(参见 source code)允许直接调用 System.exit(0)无需对应用程序进行任何修改。您只需要将止损 class 设置为 java.lang.System:

prunsrv.exe //IS//MyService ^
    --Description "MyService" ^
    --Startup auto ^
    --Classpath "D:\temp-1.0.0.jar" ^
    --StartMode jvm ^
    --StartClass org.springframework.boot.loader.JarLauncher ^
    --StopMode jvm ^
    --StopClass java.lang.System ^
    --LogPath "D:\MyService" ^
    --LogLevel Debug ^
    --StdOutput auto ^
    --StdError auto