【问题标题】:Spring boot application.properties conflict when one application deploys another当一个应用程序部署另一个应用程序时,Spring boot application.properties 冲突
【发布时间】:2018-12-11 14:36:05
【问题描述】:

我有一个 Spring Boot 应用程序,它监视和重新部署另一个 Spring Boot 应用程序。两个应用程序都使用application.properties 文件进行配置,但是当主应用程序重新部署另一个以防万一发生故障时,辅助应用程序不会获取其自己的application.properties 的配置。

辅助应用程序配置了一个 Spring 启动执行器端点,当主应用程序重新部署时,它没有被激活(我想是因为它自己的 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?

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    我有类似的情况(重新启动 docker 容器或重新启动 python 脚本)。

    我能够使用ProcessBuilder 运行任何shell 脚本。我所做的是编写一个带有cd /path/to/correct/environment/ 和实际运行代码java -jar my-client.jar 的shell 脚本。根据性质,我选择是否在后台运行它(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
    

    【讨论】:

    • 是的,ProcessExecutor 类正在被另一个拥有ExecutorService 的类调用,它包装它并通过从池中创建/重用线程来调用它,所以我使用了一个非常相似的您的解决方案。关于脚本中的cd,记得最近用过这样的解决方案,看来是问题的根源。我会再试一次您的解决方案,但我通过在DefaultExecutor 上调用setWorkingDirectory(pathOfWorkingDirectory) 找到了解决方案。我会回复以对此进行扩展。
    • 使用cd 测试了解决方案,到目前为止它没有任何问题。我将使用这个解决方案而不是setWorkingDirectory 一个,因为后者需要对我这边的路径等进行一些解析。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-07-03
    • 2017-09-30
    • 2014-11-04
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    相关资源
    最近更新 更多