当一个应用程序部署另一个应用程序时,Spring boot application.properties 发生冲突 [英] Spring boot application.properties conflict when one application deploys another

查看:22
本文介绍了当一个应用程序部署另一个应用程序时,Spring boot application.properties 发生冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Spring boot 应用程序,它监视和重新部署另一个 Spring boot 应用程序.两个应用程序都使用 application.properties 文件进行配置,但是当主应用程序在失败的情况下重新部署另一个应用程序时,辅助应用程序不会获取自己的 应用程序的配置.属性.

I have a Spring boot application that monitors and redeploys another Spring boot application. Both applications use a application.properties file for configuration, but when the main application redeploys the other one in case of failure, the secondary application doesn't pick up the configuration of its own application.properties.

辅助应用程序配置了一个 Spring 启动执行器端点,当被主应用程序重新部署时它不会被激活(我想是因为它自己的 application.properties 没有被选中).为了启用执行器端点,应该选择这些行:

The secondary app has a Spring boot actuator endpoint configured, which isn't activated when redeployed by the main one (due to its own application.properties not being picked up, I suppose). These are the lines that should be picked up in order to enable the actuator endpoint:

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 添加到此命令,但没有任何区别.

From the main application point of view, this is the command that I execute via java code: bash -c 'java -jar full_path_to_the_jar_file' & and tried adding -Dspring.config.location=file:full_path_to_appliction.properties_file to this command, but didn't make a difference.

这是用于执行重新部署的java类是这样的:

This is the java class used to execute the redeployment is this:

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?

When the same command is run on its own it works correctly and loads all the values in the application.properties file. What can I do redeploy the jar correctly from the main application?

推荐答案

我也遇到过类似的情况(重启 docker 容器或重启 python 脚本).

I had similar situation (to restart a docker container or to restart a python script).

我能够使用 ProcessBuilder 运行任何 shell 脚本.我所做的是编写一个带有 cd/path/to/correct/environment/ 和实际运行代码 java -jar my-client.jar 的 shell 脚本.根据性质,我选择是否在后台运行它(参考这个).另外,我假设您不希望执行程序线程等到客户端应用程序结束,因此我在示例中生成了一个新线程.

I was able to run any shell script using ProcessBuilder. What I did is to write a shell script with a cd /path/to/correct/environment/ and actual running of code java -jar my-client.jar. Depending on the nature, I choose whether to run it in background or not (refer to this). Also, I assume you don't want the executor thread to wait until the end of client application so I spawn a new Thread in my example.

你试过吗?

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 进程:

In the shell-script, I spawn a java process with a change-dir command:

#!/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

这篇关于当一个应用程序部署另一个应用程序时,Spring boot application.properties 发生冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆