Springboot使用ProcessBuilder创建系统进程执行shell命令备份数据库

这篇具有很好参考价值的文章主要介绍了Springboot使用ProcessBuilder创建系统进程执行shell命令备份数据库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概要

Springboot执行shell命令备份数据库。

1、查看mysql版本

mysql --version

Springboot使用ProcessBuilder创建系统进程执行shell命令备份数据库,开发问题收集,spring boot,数据库,后端

2、相关依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.20</version>
</dependency>

3、具体代码

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDate;
import org.springframework.core.io.ResourceLoader;


@Component
@Slf4j
public class BackupJob {

    //数据库连接地址
    @Value("${spring.datasource.url}")
    private String dbUrl;

    //数据库名
    @Value("${spring.datasource.name}")
    private String dbName;

    //用户名
    @Value("${spring.datasource.username}")
    private String dbUserName;

    //密码
    @Value("${spring.datasource.password}")
    private String dbPassWord;

    //存放路径
    @Value("${backup.path}")
    private String filePath;

    // 在你的类中注入ResourceLoader,用来获取备份的sql文件
    @Autowired
    private ResourceLoader resourceLoader;

    /**
     * 数据库版本是否为 8.0 + (false=否  true=是), mysql8+ 需要参数  --column-statistics=0  , mysql8- 不需要
     * 新版的mysqldump默认启用了一个新标志,通过--column-statistics=0来禁用
     */
    boolean isDbVersion8 = true;

    @SneakyThrows
    public void backup() {
        log.info("【备份数据库】--START");
        String dbUrl2 = dbUrl.replace("jdbc:mysql://", "");

        // 获取数据库地址
        String[] serverPath = dbUrl2.substring(0, dbUrl2.indexOf("/")).split(":");
        String ip = serverPath[0];
        String port = serverPath[1];

        // 数据库账号
        String username = dbUserName;
        // 数据库密码
        String password = dbPassWord;
        String dbParam = "";

        // 备份文件目录+名称  备份文件存放目录+名称(名称 = 数据库名+时间字符串.sql)
        String timeStr = LocalDate.now().toString();
        String pathFileName = filePath + dbName + "_" + timeStr + ".sql";
        String newCmd = "mysqldump -h{SERVER-PATH} -P{SERVER-PORT} -u{USERNAME} -p{PASSWORD} {DBNAME} {DB-PARAM} > {FILEPATH}";

        if(isDbVersion8){
            dbParam = "--column-statistics=0";
        }

        // 执行命令
        newCmd =  newCmd.replace("{USERNAME}", username)
                .replace("{PASSWORD}", password)
                .replace("{SERVER-PATH}", ip)
                .replace("{DBNAME}", dbName)
                .replace("{SERVER-PORT}", port)
                .replace("{FILEPATH}", pathFileName)
                .replace("{DB-PARAM}", dbParam);

        //这里打印出来的命令是可以直接在 终端执行的。
        System.out.println(newCmd);
        System.out.println(pathFileName);

        // 创建进程构建器
        ProcessBuilder processBuilder = new ProcessBuilder();
        // 设置命令和参数
        processBuilder.command(getOsShell(), "-c" , newCmd);
//        processBuilder.command(getOsShell(), "/c" , newCmd);
        // 启动进程
        Process process = processBuilder.start();

        // 获取命令执行的输出流
        InputStream inputStream = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        // 读取输出
        String line;
        while ((line = reader.readLine()) != null) {
            log.info(line);
        }

        // 等待命令执行完成
        int exitCode = process.waitFor();
        System.out.println("命令执行完成,退出码:" + exitCode);
        if (exitCode == 0) {
            log.info("数据库备份成功!");
        } else {
            log.info("数据库备份失败!");
        }

        //TODO 获取文件备份的文件、上传到云服务。
//        Resource resource = resourceLoader.getResource("file:" + pathFileName);
//        InputStream inputStream = resource.getInputStream();
//        byte[] bytes = IoUtil.readBytes(resource.getInputStream());

        //TODO 同步备份记录到数据库

        //TODO 删除指定文件
//        FileUtil.del(pathFileName);
    }

    public String getOsShell() {
        String osName = System.getProperty("os.name");
        // TODO Windows未测试
        if (osName.toLowerCase().contains("windows")) {
            return "cmd.exe";
        } else if (osName.toLowerCase().contains("mac")) {
            return "/bin/bash";
        } else if (osName.toLowerCase().contains("linux")) {
            return "/bin/bash";
        }
        return "";
    }


}

技术细节

主要就是使用ProcessBuilder创建系统进程,执行终端命令。文章来源地址https://www.toymoban.com/news/detail-727956.html

到了这里,关于Springboot使用ProcessBuilder创建系统进程执行shell命令备份数据库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot通过接口执行本地shell脚本

    首先创建springboot项目 shell脚本 这里是执行本地脚本 然后编写执行shell脚本的util类 最后开发接口调用此类 如何执行远程脚本 在这里我试用了三种方式,实现远程脚本的执行 但是使用ssh2时 会抛出上述的异常,大体的意思就是密钥交换算法不匹配,导致连接失败。 但是老版本

    2024年02月14日
    浏览(38)
  • 【Shell 命令集合 系统管理 】Linux 以超级用户(root)的身份执行特权命令 sudo命令 使用指南

    Shell 命令专栏:Linux Shell 命令全解析 sudo是Linux中的一个命令,它允许普通用户以超级用户(root)的身份执行特权命令。sudo的作用是提供了一种安全的方式,让授权用户执行需要特权的操作,而无需完全切换到超级用户账户。 sudo的主要作用如下: 提高安全性:使用sudo命令可

    2024年02月03日
    浏览(59)
  • 【Linux】在服务器上创建Crontab(定时任务),自动执行shell脚本

    业务场景:该文即为上次编写shell脚本的姊妹篇,在上文基础上,将可执行的脚本通过linux的定时任务自动执行,节省人力物力,话不多说,开始操作! 连上服务器后,在任意位置都可以执行: crontab -e 如果没有进入 编辑cron任务模式 根据提示查看我们的服务器上是否未安装crontab没有则

    2024年02月14日
    浏览(59)
  • 【Shell 命令集合 系统管理 】Linux 创建新用户的命令 useradd命令 使用指南

    Shell 命令专栏:Linux Shell 命令全解析 useradd命令是Linux系统中用于创建新用户的命令。它的作用是在系统中创建一个新的用户账号,并指定该用户的相关属性和配置。 通过useradd命令,管理员可以在Linux系统中添加新的用户账号。每个用户账号都有一个唯一的用户名和用户ID(

    2024年02月04日
    浏览(61)
  • 【Shell 命令集合 系统管理 】Linux 创建一个新的用户组 groupadd 命令 使用指南

    Shell 命令专栏:Linux Shell 命令全解析 groupadd命令用于在Linux系统中创建一个新的用户组。它可以创建一个本地用户组,也可以创建一个系统用户组。 创建一个用户组可以帮助管理员更好地管理用户和文件的权限。用户组可以将一组用户组织在一起,并为他们提供共享的权限设

    2024年02月03日
    浏览(67)
  • Java进程线程介绍创建和执行销毁并理解线程安全和线程池 Native Method

    进程和线程都是一个控制流程。 一个进程通常对应于一个程序。 一个程序可以由多个不同的线程构成。 一个进程就是一个应用程序 一个应用程序面对多个用户则多个进程 一个进程则多个线程 多个线程共享资源且携带数据操作 多进程资源隔离 多线程的核心在于多个代码块

    2024年02月02日
    浏览(45)
  • 使用 ProcessBuilder API 优化你的流程

    Java 的 Process API 为开发者提供了执行操作系统命令的强大功能,但是某些 API 方法可能让你有些疑惑,没关系,这篇文章将详细介绍如何使用 ProcessBuilder API 来方便的操作系统命令。 我们通过演示如何调用 java -version 命令输出 JDK 版本号,来演示 ProcessBuilder 的入门用法。 在这

    2024年02月08日
    浏览(54)
  • Linux下的系统编程——进程的执行与回收(八)

    前言: 前面我们对进程已经有了一个初步的了解与认识,现在让我们学习一下进程中一些函数的具体使用,比如exec可以执行一些指定的程序,wait / waitpid可以回收子进程,什么是孤儿进程,什么是僵尸进程,下面让我们一起对这些进行中的操作进行学习吧 目录 一、exec函数族

    2024年02月09日
    浏览(48)
  • linux shell pgrep命令使用方法(pgrep指令)获取进程号、统计进程数量(学会区分Linux进程进程名)

    按照我之前,在脚本中,获取除脚本自身进程之外与脚本同名进程号的方法: 这种方法有很大问题,莫名奇妙的,它无法正常过滤掉grep的进程(这里面还有点复杂,我一时半会也搞不明白咋回事,据说是grep会开子进程,并非grep那个子进程,而是开了一个与脚本相同的进程,

    2024年02月07日
    浏览(47)
  • Linux 环境使用定时任务执行shell脚本

    前言:Linux添加定时任务需要依赖crond服务,如果没有该服务,需要先安装:yum -y install crontabs 1、crond服务相关命令介绍         启动crond服务: service crond start         停止crond服务: service crond stop         重启crond服务: service crond restart         重载crond服务

    2024年02月16日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包