我有一个Spring Boot应用程序,它监视并重新部署另一个Spring Boot应用程序。这两个应用程序都使用application.properties
文件进行配置,但是如果主应用程序在发生故障时重新部署另一个文件,则辅助应用程序将不会选择其自己的application.properties
的配置。
辅助应用程序配置了一个Spring Boot执行器端点,当由主应用程序重新部署时,该端点不会被激活(我想是由于自己的application.properties
未被使用)。这些是应该启用以启用执行器端点的线:
endpoints.metrics.enabled=true
endpoints.metrics.id=metrics
endpoints.metrics.sensitive=false
从主要应用程序的角度来看,这是我通过Java代码执行的命令:
bash -c 'java -jar full_path_to_the_jar_file' &
并尝试在此命令中添加-Dspring.config.location=file:full_path_to_appliction.properties_file
,但没有任何区别。
这是用于执行重新部署的java类,是这样的:
package com.my.package;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class ProcessExecutor {
private static final Logger LOGGER =
LoggerFactory.getLogger(ProcessExecutor.class);
private final String command;
public ProcessExecutor(String command) {
Validate.notBlank(command);
this.command = command;
}
public void execute() {
LOGGER.debug("Command that will be executed: {}",
this.command);
CommandLine commandLine = CommandLine.parse(this.command);
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
try {
executor.execute(commandLine);
} catch (IOException e) {
LOGGER.error("Error restarting the process: {}",
e.getMessage());
}
}
}
单独运行同一命令时,它可以正常运行并将所有值加载到application.properties
文件中。我该如何从主应用程序中正确地重新部署jar?
答案 0 :(得分:1)
我有类似的情况(重新启动Docker容器或重新启动python脚本)。
我能够使用ProcessBuilder
运行任何shell脚本。我要做的是编写一个cd /path/to/correct/environment/
的shell脚本,并实际运行代码java -jar my-client.jar
。根据性质,我选择是否在后台运行它(refer to this)。另外,我假设您不希望执行程序线程等到客户端应用程序结束,因此在示例中生成了一个新线程。
您尝试过吗?
public static class Slave implements Runnable {
ProcessExecutor pe;
public void run () {
try {
pe._execute();
} catch (Exception e) { pe.problemCallback(); }
}
}
public class ProcessExecutor {
private static final Logger LOGGER =
LoggerFactory.getLogger(ProcessExecutor.class);
private final String command;
public ProcessExecutor(String command) {
Validate.notBlank(command);
this.command = command;
}
public void execute() {
LOGGER.debug("Command that will be executed: {}",
this.command);
try {
Slave s = new Slave();
s.pe = this;
Thread t = new Thread(s);
t.start();
} catch (IOException e) {
LOGGER.error("Error restarting the process: {}",
e.getMessage());
}
}
public void _execute() {
ProcessBuilder pb = new ProcessBuilder ("/full/path/to/shell/script.sh");
try {
Process p = pb.start();
p.waitFor();
} catch (Exception e) {}
}
public void problemCallback () {
// do something with problem.
}
}
在shell脚本中,我使用change-dir命令生成了一个Java进程:
#!/bin/bash
# correct application.properties and jar file should be in
# /path/to/correct/environment/
cd /path/to/correct/environment/
java -jar my-client.jar # put & here if you want a background
# put disown if you don't want this to die with parent