当前位置: 首页 > article >正文

NBlog Java定时任务-备份MySQL数据

NBlog部署维护流程记录(持续更新):https://blog.csdn.net/qq_43349112/article/details/136129806

为了避免服务器被攻击,给博客添加了一个MySQL数据备份功能。

此功能是配合博客写的,有些方法直接用的已有的,不会再详细展示代码。

备份大致功能步骤如下:

  • 使用mysqldump备份数据(完成)
  • 对备份文件进行压缩(完成)
  • 压缩文件上传到OSS(完成)
  • 文件清理(完成)
  • 邮件通知(TODO)
  • 适应化改造(TODO)

详细步骤见下文

CG

0.备份任务主逻辑

目前暂时使用定时任务触发,以下仅为核心代码。

    /**
     * 定时任务,每周一凌晨四点,备份MySQL的数据
     * 备份逻辑:
     * 1.mysql数据备份到文件
     * 2.备份文件压缩
     * 3.压缩文件上传到OSS
     * 4.残留文件清理
     * 5.备份结果的邮件通知 //TODO
     * 6.适应化改造,改成类似NBlog中的定时任务 //TODO
     */
    @Scheduled(cron = "0 0 4 * * 1")
    public void backUpMySQLData() {
        checkDir(backupDir);
        String dateFormat = simpleDateFormat.format(new Date());
        String fileName = String.format("cblog-%s.sql", dateFormat);
        String compressedFileName = fileName + ".zip";
        String dataPath = backupDir + File.separator + fileName;
        String compressedFilePath = backupDir + File.separator + compressedFileName;
        try {
            log.debug("mysql备份开始");
            // 1.mysql数据备份
            backupData(dataPath);
            // 2.文件压缩
            FileUtils.compressFile(dataPath, compressedFilePath);
            // 3.上传到OSS
            String uploadLink = UploadUtils.upload(compressedFilePath);
            log.info("备份文件({})已上传至OSS({})", compressedFilePath, uploadLink);
            // 4.清除残留文件
            FileUtils.delFileByPath(dataPath, compressedFilePath);
        } catch (IOException e) {
            log.error("mysql数据备份失败");
            log.error(e.getMessage());
        }
    }

1.mysqldump备份

通过Runtime.getRuntime().exec(xxx)执行备份命令,保存到指定路径下。

由于我的MySQLdocker部署,因此使用了docker exec命令。

命令的执行结果会比较长,日志级别建议低一些,下面用的debug级别。

需要注意exec(cmds)的参数格式,写错的话命令不会执行并且不报错,排查了半个下午。

    /**
     * MySQL数据备份
     * @param dataPath 备份文件的保存路径
     * @throws IOException
     */
    private void backupData(String dataPath) throws IOException {
        long start = System.currentTimeMillis();
        String cmd = String.format("docker exec mysql mysqldump -u%s -p%s cblog > %s", dataSourceProperties.getUsername(), dataSourceProperties.getPassword(), dataPath);
        String[] cmds = {"sh", "-c", cmd};
        log.debug("欲执行命令:{}", cmd);
        try (InputStream inputStream = Runtime.getRuntime().exec(cmds).getInputStream();
             InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
             BufferedReader bufferedReader = new BufferedReader(inputStreamReader);) {
            String line = bufferedReader.readLine();
            while (line != null) {
                log.debug(line);
                line = bufferedReader.readLine();
            }
        }
        long end = System.currentTimeMillis();
        log.info("mysql备份命令执行成功,耗时:{}ms", end - start);
    }

2.备份文件压缩

压缩成zip格式,核心代码如下:

     * 压缩文件到指定路径
     * @param oriFilePath 要压缩的原文件路径
     * @param compressedFilePath 压缩后的文件存放路径
     * @throws IOException IO异常,不在catch模块捕捉,交给调用方自行处理
     */
    public static void compressFile(String oriFilePath, String compressedFilePath) throws IOException {
        File file = new File(oriFilePath);
        File zipFile = new File(compressedFilePath);
        try (FileInputStream fileInputStream = new FileInputStream(file);
             ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()))){
            zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
            int temp = 0;
            while ((temp = fileInputStream.read()) != -1) {
                zipOutputStream.write(temp);
            }
        }
        log.info("文件压缩完成");
    }

3.上传至OSS

核心代码如下

    public String upload(String filepath) throws IOException {
        File file = new File(filepath);
        String uploadName = aliyunProperties.getBackupPath() + "/" + file.getName();
        PutObjectRequest putObjectRequest = new PutObjectRequest(aliyunProperties.getBucketName(), uploadName, file);
        return uploadByOSS(putObjectRequest, uploadName);
    }

    private String uploadByOSS(PutObjectRequest putObjectRequest, String uploadName) throws IOException {
        try {
            ossClient.putObject(putObjectRequest);
            return String.format("https://%s.%s/%s", aliyunProperties.getBucketName(), aliyunProperties.getEndpoint(), uploadName);
        } catch (Exception e) {
            throw new RuntimeException("阿里云OSS上传失败");
        }
    }

4.清除残留文件

上传后,备份文件和压缩文件已经无用,删除掉即可:

    public static void delFileByPath(String... paths) {
        if (paths == null) {
            return;
        }
        for (String path : paths) {
            File file = new File(path);
            del(file);
        }
    }

    private static void del(File file) {
        String filePath = file.getAbsolutePath();
        file.delete();
        log.info("{}文件已清除", filePath);
    }

5.邮件通知结果(TODO)

6.适应化改造(TODO)

NBlog定时任务可以在前端配置,自由修改触发时间,并且可以直接触发。

目前的暂时写死了,下周改造下。

X、测试

确定定时任务触发后,OSS能看到文件即可

image-20240317171232043


http://www.kler.cn/a/272493.html

相关文章:

  • 【数据分享】1929-2024年全球站点的逐日平均气温数据(Shp\Excel\免费获取)
  • 数字图像处理:实验二
  • 嵌入式知识点总结 C/C++ 专题提升(一)-关键字
  • 使用 Blazor 和 Elsa Workflows 作为引擎的工作流系统开发
  • 通过idea创建的springmvc工程需要的配置
  • R语言的文件操作
  • 分享一篇Oracle RAC实战安装11G
  • HTML5、CSS3面试题(二)
  • 【人工智能】英文学习材料01(每日一句)
  • 计算机设计大赛 题目:基于深度学习卷积神经网络的花卉识别 - 深度学习 机器视觉
  • 第一位女皇吕雉心狠手辣,斩杀韩信逼死亲儿子
  • 【爬虫逆向】Python逆向采集猫眼电影票房数据
  • 【前端】-css的详解
  • 某夕夕商品数据抓取逆向之webpack扣取
  • 旧华硕电脑开机非常慢 电脑开机黑屏很久才显示品牌logo导致整体开机速度非常的慢怎么办
  • 【目录】Java程序设计课程学习导航(更新中)
  • 2024年56套包含java,ssm,springboot的平台设计与实现项目系统开发资源(可运行源代码+设计文档)分享【万字长文收藏耐心看】
  • Sentinel篇:线程隔离和熔断降级
  • SpringBoot3框架,Web开发(下)
  • threejs案例,与静态三角形网格的基本碰撞, 鼠标环顾四周并投球游戏
  • 前端小白的学习之路(事件流)
  • System Verilog的接口、程序块与断言解析
  • vue2点击左侧的树节点(el-tree)定位到对应右侧树形表格(el-table)的位置,树形表格懒加载
  • 组合逻辑电路(四)
  • 软件测试相关内容第四弹 -- 测试用例与测试分类
  • STM32的简单介绍