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

news2024/9/20 16:15:48

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.coloradmin.cn/o/1537383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

地理坐标系与UTM坐标系转换并进行gazebo测试

地理坐标系与UTM坐标系转换并进行gazebo测试 经纬度到UTM坐标的转换gazebo测试环境 全球卫星导航系统(Global Navigation Satelite System,GNSS),简称卫星导航,是室外机器人定位的一个主要信息来源。 卫星导航能给机器人提供什么信息? 正常工…

解决Matplotlib 画图中文无法正常显示的问题(显示方框)

解决Matplotlib 画图中文无法正常显示的问题(显示方框) 错误描述解决方案一(暂时解决)解决方法二(永久解决)测试代码 错误描述 这个错误消息来自于使用 Python 的 IPython 环境,特别是在尝试输出…

基于 Google MediaPipe 进行人体姿势估计演示

用于人体姿势估计的 MediaPipe 演示 MediaPipe简介 MediaPipe是一个开源框架,用于构建跨平台、多模式应用机器学习管道。它由 Google 开发,旨在促进基于机器学习的功能的快速开发和部署,特别关注音频、视频和时间序列数据。 我可以将 MediaPi…

高标准农业四情监测系统的应用范围

高标准农业四情监测系统的应用范围【TH-Q1】随着科技的不断进步,高标准农业四情监测系统已经逐渐成为现代农业的重要组成部分。这一系统能够实时监测土壤、气候、作物生长和病虫害情况,为农业生产提供精准的数据支持,从而提高农作物的产量和质…

小红书离线数仓提效新思路,提升百倍回刷性能

数据处理效率一直是大数据时代的核心话题,它推动着各类数据执行引擎持续迭代产品。从早期的 MapReduce,到今天的 Spark,各行业正不断演进其离线数仓技术架构。 现有以 Spark 为核心的数仓架构在处理大规模数据回刷方面已取得进展,…

第十节HarmonyOS 常用容器组件2-Counter

1、描述 计数器组件,提供相应的增加或者减少的计数操作。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 2、子组件 可以包含子组件。 3、接口 Counter() 从API version 9开始…

项目实战-开发工具入门/基本框架搭建/项目初始化/引入组件库

上周更新完了之前vue3的shopping项目,接下来,将会开启一个新的项目,效果是类似于移动端的一个伙伴匹配项目,今天这篇文章从需求分析到架构设计再到项目初始化,基本框架搭建几个部分来为大家详细介绍。 从这个项目开始…

java面试:常见的限流算法有哪些

1 什么是限流算法 限流算法是一种用于限制流量请求的频率或速率的算法,其目的是在高并发或大流量请求的情况下,保护系统服务的安全性和可用性。限流算法可以应对热点业务带来的突发请求、调用方bug导致的突发请求以及恶意攻击请求等情况。是一种系统保护…

linux之sed编辑器指令练习

目录 一、sed编辑器 二、sed使用案例 1.1 s命令(substitute替换) 一、sed编辑器 sed编辑器比交互式编辑器快的多,可以简化数据处理任务,sed编辑器并不会修改文件,只会将修改后的数据,输出。 二、sed使用案例 首先…

【国家计算机二级C语言】高分笔记

二叉树 参考 http://t.csdnimg.cn/ozVwT 数据库 SQL程序语言有四种类型,对数据库的基本操作都属于这四类,它们分别为;数据定义语言(DDL)、数据查询语言(DQL)、数据操纵语言(DML)、数据控制语言…

【数据结构与算法】(18):树形选择排序:按照锦标赛的思想进行排序

🤡博客主页:Code_文晓 🥰本文专栏:数据结构与算法 😻欢迎关注:感谢大家的点赞评论关注,祝您学有所成! ✨✨💜💛想要学习更多数据结构与算法点击专栏链接查看&…

yaml 语法和在线解析工具

文章目录 在线解析工具1. 简介2. 语法规则3. 数据类型3.1 数组:3.2对象:3.3 标量3.4 复合结构3.5 锚点3.5.1 单个锚点3.5.6 多个锚点 3.6 引号 参考 在线解析工具 工具1 工具2 1. 简介 Yaml是一种可读性高的数据标记语言,Yaml文件是一种配…

6 修改主机名和HOSTS文件

后期我们会配置多台服务器,那么每台服务器我们都会给定一个主机名,方便后期通过主机名进行访问。主机名的修改我们可以在安装操作系统时对其修改,如果忘记了,就可以修改配置文件完成,像后期我们进行虚拟机克隆后&#…

Docker常用命令练习

文章目录 Docker常用命令练习1.docker 基础命令2.镜像命令3.保存镜像4.加载镜像5.容器命令6.环境变量7. --rm8. --networkhost Docker常用命令练习 1.docker 基础命令 安装docker yum install docker启动docker systemctl start docker关闭docker systemctl stop docker重…

LeetCode-热题100:17.电话号码的字母组合

题目描述 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入: digits “23” 输出&a…

2024年【P气瓶充装】复审模拟考试及P气瓶充装操作证考试

题库来源:安全生产模拟考试一点通公众号小程序 P气瓶充装复审模拟考试根据新P气瓶充装考试大纲要求,安全生产模拟考试一点通将P气瓶充装模拟考试试题进行汇编,组成一套P气瓶充装全真模拟考试试题,学员可通过P气瓶充装操作证考试全…

【阿里云物联网】上报设备数据

前言 MQTT客户端上传数据到阿里云服务端,并且能将数据显示出来。在此之前,我们先要懂得阿里云给设备管理划分的概念。首先是产品,所以在产品里要配置内容,产品下的设备才可以使用,比如主题大类都是在产品里面就可以查…

使用 Amazon SageMaker 微调 Llama 2 模型

本篇文章主要介绍如何使用 Amazon SageMaker 进行 Llama 2 模型微调的示例。 这个示例主要包括: Llama 2 总体介绍Llama 2 微调介绍Llama 2 环境设置Llama 2 微调训练 前言 随着生成式 AI 的热度逐渐升高,国内外各种基座大语言竞相出炉,在其基础上衍生出…

I2C芯片24C02/4/8/16(EEPROM)解读

一.原理图 24C01的硬件连接图如下: 二.24C0x系列芯片规格 三.24C0x芯片结构 下面简述EEPROM内部存储结构。 3.1 内部存储结构 根据24C02芯片的Datasheet描述,其内部存储结构应该如下图所示。 其它容量的EEPROM内部结构依此类推。 3.2 地址 3.2.1 器件…

BitMap介绍与应用

文章目录 BitMapBitMap介绍BitMap 结构RoaringBitmap 常见BitMapJava中的BitSetRedis中的BitMapClickHouse中的BitMap BitMap应用案例人群圈选 BitMap 场景一:(大部分开发面试都会遇到的一个问题) 有10亿个用户id (int类型),判断用户是否登…