从Bash脚本中启动Spring Boot作为前台进程

yer*_*lin 9 java bash spring war

我使用嵌入式Tomcat servlet容器打包Spring Boot war.并使用它将其部署为常规Java应用程序java -jar server.war <Spring Args>.我编写了一个bash脚本,负责将服务器部署为后台/前台进程:

start_foreground() {
    cmd="$JAVACMD ${JVM_OPTS} -jar ${WAR_FILE} ${SPRING_OPTS}"
    echo "\"${cmd}\""
    eval ${cmd}
    print_log "Server is stopped."
}

start_background() {
    SPRING_OPTS="--spring.pid.file=${PID_FILE} ${SPRING_OPTS}"
    cmd="nohup $JAVACMD ${JVM_OPTS} -jar ${WAR_FILE} ${SPRING_OPTS} &>${LOG_PATH}/console.log &"
    echo "\"${cmd}\""
    eval ${cmd}
    PID=$!
    print_log "Server is started with pid \"${PID}\""
}
Run Code Online (Sandbox Code Playgroud)

如您所见,对于后台进程启动我使用nohup.一切工作正常,它发送STDOUTSTDERR给我的${LOG_PATH}/console.log.console.log报告我的服务器在预配置端口上启动并运行(使用Spring配置文件).我有一个dev-https配置端口的配置文件8443:

spring:
  profiles.active: dev-https
...
---

spring:
    profiles: dev-https
server:
  port: 8443
  ssl:
    enabled: true
    protocol: TLS
    enabled-protocols: TLSv1.2
    key-store: <path>
    key-store-password: <password>
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试将服务器作为前台进程启动时,我会遇到意外行为.每当我使用服务器部署时start_foreground(),它都会正常启动,但端口会重置为默认值8080.

如果我附加一个调试器,并尝试使用environment.getProperty("server.port")它来获取值,它将返回空字符串(但是,如果未定义属性,则通常返回null).此外,所有其他属性返回预期值:

environment.getProperty("spring.profiles.active")=dev-https

environment.getProperty("server.ssl.enabled")=true

等等

我尝试eval用bash函数替换,exec甚至${cmd}自己运行start_foreground(),但是端口总是重置为8080,并server.port返回空字符串.

最奇怪的部分是,如果我${cmd}在我的控制台中执行(而不是从脚本中执行),一切都可以完美运行(正确的配置文件,并使用正确的端口).

有谁遇到过这样奇怪的问题?

yer*_*lin 1

我尝试使用 Spring Boot 的新实例重现此问题。编写了一个快速的 bash 脚本,一切都很顺利!

然后,我开始尝试我的原始脚本,发现我正在使用变量(因为我有一个用户的SERVER_PORT可选参数)。--port <num>

显然,Spring框架也使用这个环境变量:https://www.concretepage.com/spring-boot/spring-boot-change-default-server-port#server_port

我的错误是导出SERVER_PORTvar (但是,我出于其他原因需要它)。

解决方案是删除export变量export SERVER_PORT=""或将变量重命名为其他内容(我最终这样做了)。