我使用嵌入式Tomcat servlet容器打包Spring Boot war。并使用java -jar server.war <Spring Args>
将其部署为常规Java应用程序。我编写了一个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}\""
}
如您所见,对于后台处理开始,我使用nohup
。一切正常,它会将STDOUT
和STDERR
发送到我的${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>
但是,当我尝试将服务器作为前台进程启动时,我会遇到意外行为。每当我使用start_foreground()
部署服务器时,它都会正常启动,但端口会重置为默认8080
。
如果我附加调试器,并尝试使用environment.getProperty("server.port")
获取值,它将返回空字符串(但是,如果未定义属性,则通常返回null
)。此外,所有其他属性都返回预期值:
environment.getProperty("spring.profiles.active")=dev-https
environment.getProperty("server.ssl.enabled")=true
等
我尝试将eval
替换为exec
,甚至在${cmd}
bash函数中自行运行start_foreground()
,但该端口始终重置为8080
,并且server.port
返回空字符串。
最奇怪的部分是,如果我在我的控制台中执行${cmd}
(而不是在脚本中),一切都可以正常工作(正确的配置文件,并使用正确的端口)。
有没有人遇到过这样奇怪的问题?
答案 0 :(得分:2)
看起来你正在使用配置(如端口号等...仅用于后台而不用于前台。你还没有声明变量(你错过了这一行)
`SPRING_OPTS="--spring.pid.file=${PID_FILE} ${SPRING_OPTS}"`
为前景。
答案 1 :(得分:1)
我尝试使用Spring Boot的新实例重现此问题。写了一个快速的bash脚本,一切都很顺利!
然后,我开始玩我的原始脚本,发现我使用的是SERVER_PORT
变量(因为我为用户提供了一个可选参数--port <num>
。)
显然,Spring Framework也使用了这个环境变量:https://www.concretepage.com/spring-boot/spring-boot-change-default-server-port#server_port
我的错误是导出SERVER_PORT
var(但是,出于其他原因我需要它)。
解决方法是从export
移除export SERVER_PORT=""
或将变量重命名为其他内容(我最终会这样做)。