从 SpringBoot 应用程序内部运行 ProcessBuilder 进程经常挂起并且不执行命令

问题描述 投票:0回答:0

首先,这是一个在 Docker 容器中运行的 SpringBoot 应用程序。

应用程序将为每个配置的租户执行 Liquibase 更新。在这种情况下,有 3 个租户。

我发现它 might 为租户 001 成功执行(或者它可能挂起),然后挂在前面列出的同一点的第二个或第三个租户上。

我已将

ProcessBuilder
设置为
redirectErrorStream(true)
inheritIO()
,但这对 API/命令的可靠性没有任何影响。

我在这里做错了什么?

对一个租户成功的相同命令可能会挂在另一个租户上,即使租户状态或数据库没有差异..所有租户在这一刻都是平等的。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Component;

@Component
public class MyComponent {
  public MyComponent() throws Exception {
    
    System.out.println("RB");

    List<String> tenants = Arrays.asList("001", "002schema", "003_schema");

    for (String tenant : tenants) {

      ProcessBuilder processBuilder = new ProcessBuilder();
      processBuilder.redirectErrorStream(true);
      processBuilder.inheritIO();

      System.out.println("Liquibase update: " + tenant);

      processBuilder.command(
          "/home/liquibase/liquibase",
          "--url=jdbc:postgresql://localhost:5432/postgres?currentSchema=" + tenant,
          "--changeLogFile=config/liquibase/changelog/root-changelog.xml",
          "--username=postgres",
          "--password=password",
          "--search-path=/home/",
          "--liquibase-schema-name=" + tenant,
          "--preserveSchemaCase=true",
          "update");

      System.out.println(processBuilder);

      Process process = processBuilder.start();

      System.out.println("Started");

      StringBuilder output = new StringBuilder();
      BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
      System.out.println("Buffer created");

      String line;
      while ((line = reader.readLine()) != null) {
        output.append(line + "\n");
      }
      System.out.println("Read lines from buffer");

      int exitVal = process.waitFor();
      System.out.println("Waited for process");
      if (exitVal == 0) {
        System.out.println("Success!");
        System.out.println(output);
      } else {
        System.out.println("Error!");
        System.out.println(output);
      }

      reader.close();
      process.destroy();
    }
  }
}

这是日志的输出:

2023-03-24 22:39:00.515  INFO 30 --- [           main] c.c.c.d.migration.SpringBootApplication  : Starting SpringBootApplication using Java 17.0.6 on docker-desktop with PID 30 (/home/app-0.1.0-SNAPSHOT.jar started by user in /home)
2023-03-24 22:39:00.528  INFO 30 --- [           main] c.c.c.d.migration.SpringBootApplication  : No active profile set, falling back to 1 default profile: "default"
RB
Liquibase update: 001
java.lang.ProcessBuilder@d35dea7
Started
Buffer created
Read lines from buffer
####################################################
##   _     _             _ _                      ##
##  | |   (_)           (_) |                     ##
##  | |    _  __ _ _   _ _| |__   __ _ ___  ___   ##
##  | |   | |/ _` | | | | | '_ \ / _` / __|/ _ \  ##
##  | |___| | (_| | |_| | | |_) | (_| \__ \  __/  ##
##  \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___|  ##
##              | |                               ##
##              |_|                               ##
##                                                ## 
##  Get documentation at docs.liquibase.com       ##
##  Get certified courses at learn.liquibase.com  ## 
##  Free schema change activity reports at        ##
##      https://hub.liquibase.com                 ##
##                                                ##
####################################################
Starting Liquibase at 22:39:12 (version 4.20.0 #7837 built at 2023-03-07 16:25+0000)
Liquibase Version: 4.20.0
Liquibase Open Source 4.20.0 by Liquibase
Database is up to date, no changesets to execute
Liquibase command 'update' was executed successfully.
Waited for process
Success!

Liquibase update: 002schema
java.lang.ProcessBuilder@5fbe4146
Started
Buffer created
Read lines from buffer

java spring-boot processbuilder
© www.soinside.com 2019 - 2024. All rights reserved.